Load in libraries


library(tidyverse)
library(here)
library(janitor)
library(tsibble)
library(lubridate)
library(sf)

Load in data sets


waiting_times_raw <- read_csv(here("raw_data/non_covid/monthly_ae_waitingtimes_202206.csv")) %>% 
  clean_names()

hb <- read_csv(here("clean_data/hb_list_simple.csv"))

hospitals <- read_csv(here("raw_data/general/current-hospital_flagged20211216.csv")) %>% 
  clean_names() %>% 
  select(location, location_name)

clean dataset

The following cleaning does the following to the waiting times data set: - converts month column to year_month dates and extracts years and months
- joins health board and hospital names to data set
- renames columns to more easily understandable names
- removes columns relating to “episodes”, “qualifier codes” and “discharges” - adds new value of wait greater than 4 hours to the data
- replaces all NA values with 0 (this step may be optional)

Please note that 4 hours wait time is the “Target” wait time for the NHS and is represented by the “wait_lt_4hrs” column values.

# cleaning script
waiting_times <- waiting_times_raw %>% 
  mutate(date_ym = ym(month), .before = month,
         month = month(date_ym, label = TRUE, abbr = FALSE),
         year = year(date_ym)) %>% 
  left_join(hb, c("hbt" = "hb")) %>% 
  left_join(hospitals, c("treatment_location" = "location")) %>% 
  rename(total_attendance = number_of_attendances_aggregate,
         wait_lt_4hrs = number_meeting_target_aggregate,
         wait_gt_8hrs = attendance_greater8hrs,
         wait_gt_12hrs = attendance_greater12hrs,
         hospital_id = treatment_location, 
         hospital_name = location_name) %>%
  select(date_ym, year, month, hb_name, hospital_id, hospital_name, department_type,
         total_attendance, wait_lt_4hrs, wait_gt_8hrs, wait_gt_12hrs) %>% 
  mutate(wait_gt_4hrs = total_attendance - wait_lt_4hrs, .after = wait_lt_4hrs) %>%
  mutate(across(total_attendance:wait_gt_12hrs, .fns = ~coalesce(., 0)))

waiting_times <- read_csv(here("clean_data/wait_times.csv")) %>% 
  mutate(month = month(date_ym, label = TRUE, abbr = FALSE)) 
# create table with proportions of wait times used for the analysis
waiting_times_prop <- waiting_times %>% 
  pivot_longer(contains("wait"), names_to = "wait_category", values_to = "number_of_attendances") %>% 
  mutate(wait_prop = number_of_attendances / total_attendance,
         wait_category = str_replace(wait_category, "wait", "prop")) %>% 
  select(-number_of_attendances) %>% 
  pivot_wider(names_from = wait_category, values_from = wait_prop)


waiting_times_prop

Analysis

How does hospital attendances change with time?

# plot all data - attendances per year
waiting_times %>% 
  group_by(year) %>% 
  summarise(total_attendance = sum(total_attendance)) %>% 
  ggplot(aes(x = year, y = total_attendance)) +
  geom_line()

# attendances - all data covid seasonal analysis
waiting_times %>% 
  group_by(year, month) %>% 
  summarise(total_attendance = sum(total_attendance)) %>% 
  ggplot(aes(x = month, y = total_attendance, group = year, col = factor(year))) +
  geom_line()

# attendances per month - pre-covid seasonal analysis
waiting_times %>% 
  filter(year < 2020) %>% 
  group_by(year, month) %>% 
  summarise(total_attendance = sum(total_attendance)) %>% 
  ggplot(aes(x = month, y = total_attendance, group = year, col = factor(year))) +
  geom_line()

# attendances per month - covid seasonal analysis
waiting_times %>% 
  filter(year >= 2020) %>% 
  group_by(year, month) %>% 
  summarise(total_attendance = sum(total_attendance)) %>% 
  ggplot(aes(x = month, y = total_attendance, group = year, col = factor(year))) +
  geom_line()

health_board_input <- c("Borders", "Lothian", "Ayrshire and Arran", "Dumfries and Galloway")

# health_board_input <- hb$hb_name

paste("Multiple HB:\n", paste(sort(health_board_input), collapse = ", "), sep = "\n")

str_c("Multiple HBs:\n", str_c("Borders", "Lothian", "Dumfries", sep = ",\n"))

# plot all data - attendances per year

  
  if(length(health_board_input) <= 3) {
   
    #first two rows will be from reactive function
    p <- waiting_times %>% 
      filter(hb_name %in% health_board_input) %>% 
      group_by(date_ym, hb_name) %>% 
      summarise(total_attendance = sum(total_attendance)) %>% 
      ggplot(aes(x = date_ym, y = total_attendance, col = hb_name)) +
      geom_line()

  } else {
    
    if(length(health_board_input) == 14) {
      hb_label <- "All Health Boards"
    } else {
      hb_label <- str_c("Total of Multiple HBs:\n",
                        str_c(health_board_input, collapse = ",\n"))
    }
 
    p <- waiting_times %>% 
      filter(hb_name %in% health_board_input) %>% 
      mutate(hb_label = hb_label) %>% 
      group_by(date_ym) %>% 
      summarise(total_attendance = sum(total_attendance)) %>% 
      ggplot(aes(x = date_ym, y = total_attendance, colour = hb_label)) +
      geom_line()
    
  }

p  +
  theme_classic() +
  scale_y_continuous(labels = comma, 
                     expand = c(0, 0),
                     limits = c(0, NA)) +
  scale_x_date(date_labels = "%Y",
               date_breaks = "1 year") +
  labs(title = "Total hospital attendances",
       subtitle = "July 2007 to June 2022", 
       col = "Health Board",
       y = "Total attendances") +
  theme(axis.title.x = element_blank(),
        axis.text.x = element_text(angle = 45, hjust = 1),
        legend.text.align = 0)

How do wait times change per year? (in terms of numbers)

# wait times less than 4 hours
waiting_times %>% 
  group_by(year) %>% 
  summarise(wait_lt_4hrs = sum(wait_lt_4hrs)) %>% 
  ggplot(aes(x = year, y = wait_lt_4hrs)) +
  geom_col()

# wait times more than 4 hours
waiting_times %>% 
  group_by(year) %>% 
  summarise(wait_gt_4hrs = sum(wait_gt_4hrs)) %>% 
  ggplot(aes(x = year, y = wait_gt_4hrs)) +
  geom_col()

# wait times more than 8 hours
waiting_times %>% 
  group_by(year) %>% 
  summarise(wait_gt_8hrs = sum(wait_gt_8hrs)) %>% 
  ggplot(aes(x = year, y = wait_gt_8hrs)) +
  geom_col()

# wait times more than 12 hours
waiting_times %>% 
  group_by(year) %>% 
  summarise(wait_gt_12hrs = sum(wait_gt_12hrs)) %>% 
  ggplot(aes(x = year, y = wait_gt_12hrs)) +
  geom_col()

How do wait times change per year? (in terms of proportion)


# wait times less than 4 hours
waiting_times %>% 
  group_by(year) %>% 
  summarise(total_attendance = sum(total_attendance),
            wait_lt_4hrs = sum(wait_lt_4hrs),
            prop_lt_4hrs = wait_lt_4hrs / total_attendance) %>% 
  ggplot(aes(x = year, y = prop_lt_4hrs)) +
  geom_col()

# wait times more than 4 hours
waiting_times %>% 
  group_by(year) %>% 
  summarise(total_attendance = sum(total_attendance),
            wait_gt_4hrs = sum(wait_gt_4hrs),
            prop_gt_4hrs = wait_gt_4hrs / total_attendance) %>% 
  ggplot(aes(x = year, y = prop_gt_4hrs)) +
  geom_col()

# wait times more than 8 hours
waiting_times %>% 
  group_by(year) %>% 
  summarise(total_attendance = sum(total_attendance),
            wait_gt_8hrs = sum(wait_gt_8hrs),
            prop_gt_8hrs = wait_gt_8hrs / total_attendance) %>% 
  ggplot(aes(x = year, y = prop_gt_8hrs)) +
  geom_col()

# wait times more than 12 hours
waiting_times %>% 
  group_by(year) %>% 
  summarise(total_attendance = sum(total_attendance),
            wait_gt_12hrs = sum(wait_gt_12hrs),
            prop_gt_12hrs = wait_gt_12hrs / total_attendance) %>% 
  ggplot(aes(x = year, y = prop_gt_12hrs)) +
  geom_col() +
  scale_y_continuous(expand = c(0,0),
                     labels = scales::percent) +
  theme_classic() +
  theme(axis.title.x = element_blank()) +
  labs(y = "Percentage of attendances greater than 12 hours",
       title = "Wait times of >12hours each year")

How do wait times differ between departments? (in terms of proportions)


# wait times less than 4 hours
waiting_times %>% 
  group_by(year, department_type) %>% 
  summarise(total_attendance = sum(total_attendance),
            wait_lt_4hrs = sum(wait_lt_4hrs),
            prop_lt_4hrs = wait_lt_4hrs / total_attendance) %>% 
  ggplot(aes(x = year, y = prop_lt_4hrs, fill = department_type)) +
  geom_col(position = "dodge")

# wait times more than 4 hours
waiting_times %>% 
  group_by(year, department_type) %>% 
  summarise(total_attendance = sum(total_attendance),
            wait_gt_4hrs = sum(wait_gt_4hrs),
            prop_gt_4hrs = wait_gt_4hrs / total_attendance) %>% 
  ggplot(aes(x = year, y = prop_gt_4hrs, fill = department_type)) +
  geom_col(position = "dodge")

# wait times more than 8 hours
waiting_times %>% 
  group_by(year, department_type) %>% 
  summarise(total_attendance = sum(total_attendance),
            wait_gt_8hrs = sum(wait_gt_8hrs),
            prop_gt_8hrs = wait_gt_8hrs / total_attendance) %>% 
  ggplot(aes(x = year, y = prop_gt_8hrs, fill = department_type)) +
  geom_col(position = "dodge")

# wait times more than 12 hours
waiting_times %>% 
  group_by(year, department_type) %>% 
  summarise(total_attendance = sum(total_attendance),
            wait_gt_12hrs = sum(wait_gt_12hrs),
            prop_gt_12hrs = wait_gt_12hrs / total_attendance) %>% 
  ggplot(aes(x = year, y = prop_gt_12hrs, fill = department_type)) +
  geom_col(position = "dodge")

How do wait times change per year & month? (in terms of numbers)

# wait times less than 4 hours
waiting_times %>% 
  group_by(year, month) %>% 
  summarise(wait_lt_4hrs = sum(wait_lt_4hrs)) %>% 
  ggplot(aes(x = month, y = wait_lt_4hrs, group = year, col = factor(year))) +
  geom_line()

# wait times more than 4 hours
waiting_times %>% 
  group_by(year, month) %>% 
  summarise(wait_gt_4hrs = sum(wait_gt_4hrs)) %>% 
  ggplot(aes(x = month, y = wait_gt_4hrs, group = year, col = factor(year))) +
  geom_line()

# wait times more than 8 hours
waiting_times %>% 
  group_by(year, month) %>% 
  summarise(wait_gt_8hrs = sum(wait_gt_8hrs)) %>% 
  ggplot(aes(x = month, y = wait_gt_8hrs, group = year, col = factor(year))) +
  geom_line()

# wait times more than 12 hours
waiting_times %>% 
  group_by(year, month) %>% 
  summarise(wait_gt_12hrs = sum(wait_gt_12hrs)) %>% 
  ggplot(aes(x = month, y = wait_gt_12hrs, group = year, col = factor(year))) +
  geom_line()

How do wait times vary across health boards?

# in terms of numbers
waiting_times %>% 
  group_by(date_ym, health_board) %>% 
  summarise(wait_gt_8hrs = sum(wait_gt_8hrs)) %>% 
  ggplot(aes(x = date_ym, y = wait_gt_8hrs, col = health_board)) +
  geom_line() +
  labs(title = "Number of waits > 8 hours for each healthboard")

# in terms of proportion
waiting_times_prop %>% 
  group_by(date_ym, health_board) %>% 
  summarise(prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/
              sum(total_attendance)) %>% 
  ggplot(aes(x = date_ym, y = prop_gt_8hrs, col = health_board)) +
  geom_line() +
  labs(title = "Proportion of waits > 8 hours for each healthboard")


# find top 5 healthboards (in terms of attendances)
top_5_attendances_by_hb <- waiting_times_prop %>% 
  group_by(health_board) %>% 
  summarise(total_att = sum(total_attendance)) %>% 
  slice_max(total_att, n = 5)

# find bottom 5 healthboards (in terms of attendances)
bottom_5_attendances_by_hb <- waiting_times_prop %>% 
  group_by(health_board) %>% 
  summarise(total_att = sum(total_attendance)) %>% 
  slice_min(total_att, n = 5)

# wait times across the top 5 healthboards > 8 hours
waiting_times_prop %>% 
  filter(health_board %in% top_5_attendances_by_hb$health_board) %>% 
  group_by(date_ym, health_board) %>% 
  summarise(prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/
              sum(total_attendance)) %>% 
  ggplot(aes(x = date_ym, y = prop_gt_8hrs, col = health_board)) +
  geom_line() +
  labs(title = "Proportion of waits > 8 hours for the top 5 most attended healthboards")

# wait times across the bottom 5 healthboards > 8 hours
waiting_times_prop %>% 
  filter(health_board %in% bottom_5_attendances_by_hb$health_board) %>% 
  group_by(date_ym, health_board) %>% 
  summarise(prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/
              sum(total_attendance)) %>% 
  ggplot(aes(x = date_ym, y = prop_gt_8hrs, col = health_board)) +
  geom_line() +
  labs(title = "Proportion of waits > 8 hours for the bottom 5 most attended healthboards")


# wait times across the top 5 healthboards > 12 hours
waiting_times_prop %>% 
  filter(health_board %in% top_5_attendances_by_hb$health_board) %>% 
  group_by(date_ym, health_board) %>% 
  summarise(prop_gt_12hrs = sum(total_attendance * prop_gt_12hrs)/
              sum(total_attendance)) %>% 
  ggplot(aes(x = date_ym, y = prop_gt_12hrs, col = health_board)) +
  geom_line() +
  labs(title = "Proportion of waits > 12 hours for the bottom 5 most attended healthboards")

# wait times across the bottom 5 healthboards > 12 hours
waiting_times_prop %>% 
  filter(health_board %in% bottom_5_attendances_by_hb$health_board) %>% 
  group_by(date_ym, health_board) %>% 
  summarise(prop_gt_12hrs = sum(total_attendance * prop_gt_12hrs)/
              sum(total_attendance)) %>% 
  ggplot(aes(x = date_ym, y = prop_gt_12hrs, col = health_board)) +
  geom_line() +
  labs(title = "Proportion of waits > 12 hours for the bottom 5 most attended healthboards")

# wait times across each hospital in the Borders healthboard
waiting_times_prop %>% 
  # filter(health_board == "NHS Borders") %>% 
  group_by(date_ym, hospital_name) %>% 
  summarise(prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/
              sum(total_attendance)) %>% 
  ggplot(aes(x = date_ym, y = prop_gt_8hrs, col = hospital_name)) +
  geom_line() +
  labs(title = "Proportion of waits > 8 hours for the bottom 5 most attended healthboards") +
  theme(legend.position = "none")

most affected healthboards

# in terms of proportion
top_5_hospital_props <- waiting_times_prop %>% 
  group_by(hospital_name) %>% 
  summarise(max_prop = max(prop_gt_12hrs)) %>% 
  arrange(desc(max_prop)) %>% 
  slice_max(max_prop, n = 5)
  
# in terms of numbers
waiting_times %>% 
  group_by(hospital_name) %>% 
  summarise(max_prop = max(wait_gt_12hrs)) %>% 
  arrange(desc(max_prop))

# wait times across each hospital in the Borders healthboard
waiting_times_prop %>% 
  filter(hospital_name %in% top_5_hospital_props$hospital_name) %>% 
  group_by(date_ym, hospital_name) %>% 
  summarise(prop_gt_12hrs = sum(total_attendance * prop_gt_12hrs)/
              sum(total_attendance)) %>% 
  ggplot(aes(x = date_ym, y = prop_gt_12hrs, col = hospital_name)) +
  geom_line() +
  labs(title = "Proportion of waits > 8 hours for the bottom 5 most attended healthboards")

For the years 2007 to 2019, provide a summary of the effects of wait times at different times of the year.


waiting_times_summary <- waiting_times_prop %>% 
  filter(year <= 2019) %>% 
  mutate(month = factor(month, levels = c("July", "August", "September", "October", "November", "December", "January", "February", "March", "April", "May", "June"))) %>% 
  group_by(month) %>% 
  summarise(total_attends = mean(total_attendance),
            prop_lt_4hrs = sum(total_attendance * prop_lt_4hrs)/ sum(total_attendance),
            prop_gt_4hrs = sum(total_attendance * prop_gt_4hrs)/ sum(total_attendance),
            prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/ sum(total_attendance),
            prop_gt_12hrs = sum(total_attendance * prop_gt_12hrs)/ sum(total_attendance)) 

waiting_times_summary %>% 
  ggplot(aes(x = month, y = total_attends)) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        axis.title.x = element_blank()) +
  labs(y = "Average monthly attendances",
       title = "Average A&E attendances",
       subtitle = "From July 2007 to December 2019 ") +
  geom_smooth()

waiting_times_summary %>% 
  ggplot(aes(x = month, y = prop_lt_4hrs, group = 1)) +
  geom_point() +
  labs(title = "Seasonality of proportion of visits with a wait time < 4 hours",
         subtitle = "2007 to 2019") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  geom_smooth()

waiting_times_summary %>% 
  ggplot(aes(x = month, y = prop_gt_4hrs, group = 1)) +
  geom_point() +
    labs(title = "Seasonality of proportion of visits with a wait time > 4 hours",
         subtitle = "2007 to 2019") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  geom_smooth()


waiting_times_summary %>%
  ggplot(aes(x = month, y = prop_gt_8hrs, group = 1)) +
  geom_point() +
    labs(title = "Seasonality of proportion of visits with a wait time > 8 hours",
         subtitle = "2007 to 2019") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  geom_smooth()


waiting_times_summary %>% 
  ggplot(aes(x = month, y = prop_gt_12hrs, group = 1)) +
  geom_point() +
    scale_y_continuous(labels = scales::percent) +
    labs(title = "Seasonality of proportion of visits with a wait time > 12 hours",
         subtitle = "Pre-covid: 2007 to 2019",
         y = "Percentage of attendances > 12 hours") +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        axis.title.x = element_blank()) +
  geom_smooth(se = FALSE)

The number of A&E attendances decrease during the winter months however the proportion of wait times greater than 4hours increases significantly between November and February highlighting that the complexity of cases in the winter mean that it takes hospitals longer to discharge patients. Perhaps combining this output with the bed occupation rates during the winter months could further supplement this relationship.


waiting_times_prop %>% 
  # filter(year <= 2019) %>% 
  mutate(month = factor(month, levels = c("July", "August", "September", "October", "November", "December", "January", "February", "March", "April", "May", "June"))) %>% 
  group_by(month, health_board) %>% 
  summarise(total_attends = mean(total_attendance),
            prop_lt_4hrs = sum(total_attendance * prop_lt_4hrs)/ sum(total_attendance),
            prop_gt_4hrs = sum(total_attendance * prop_gt_4hrs)/ sum(total_attendance),
            prop_gt_8hrs = sum(total_attendance * prop_gt_8hrs)/ sum(total_attendance),
            prop_gt_12hrs = sum(total_attendance * prop_gt_12hrs)/ sum(total_attendance)) %>% 
  ggplot(aes(x = month, y = prop_gt_12hrs, group = health_board, colour = health_board)) +
  geom_line() +
  labs(title = "Seasonality of proportion of visits with a wait time > 12 hours") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

How do attendances to different specialties change over time?


specialties_raw <- read_csv(here("raw_data/non_covid/inpatient_and_daycase_by_nhs_board_of_treatment_and_specialty.csv")) %>%
  clean_names()

specialties_raw

specialties <- specialties_raw %>% 
  inner_join(hb, "hb") %>% 
  inner_join(hospitals, "location") %>% 
  select(-ends_with("qf"), -hb, - specialty) %>% 
  select(quarter, hb_name, location, location_name, everything()) %>% 
  mutate(year = as.numeric(str_sub(quarter,1, 4)), .before = quarter) %>% 
  mutate(is_covid_year = case_when(
    year >= 2020 ~ TRUE,
    year < 2020 ~ FALSE
  ))
  # mutate(quarter = str_sub(quarter, -2, -1))

specialties

all episodes vs time


specialties %>% 
  distinct(admission_type)

specialties %>% 
  group_by(quarter) %>% 
  filter(admission_type == "All Inpatients and Day cases") %>% 
  summarise(total_episodes = sum(episodes)) %>% 
  ggplot(aes(x = quarter, y = total_episodes, group = 1)) +
  geom_line() +
  geom_point() +
  theme_classic() +
  scale_y_continuous(labels = scales::comma, expand = c(0,0), limits = c(0,NA)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title = "Total admissions for All Inpatients and Day Cases",
       x = "Quarter",
       y = "Total Episodes")

All Day Cases


specialties %>% 
  distinct(admission_type)

specialties %>% 
  group_by(quarter, admission_type) %>% 
  filter(admission_type %in% c("All Day cases", "All Inpatients")) %>% 
  summarise(total_episodes = sum(episodes)) %>% 
  ggplot(aes(x = quarter, y = total_episodes, colour = admission_type)) +
  geom_line(aes(group = admission_type)) +
  geom_point() +
  theme_classic() +
  scale_y_continuous(labels = scales::comma, expand = c(0,0), limits = c(0,NA)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title = "Total admissions for All Day Cases and All Inpatients",
       x = "Quarter",
       y = "Total Episodes",
       col = "Admission Type")

all_inpatient_cats <- c("Elective Inpatients",
                          "Emergency Inpatients",
                          "Transfers")

specialties %>% 
  group_by(quarter, admission_type) %>% 
  filter(admission_type %in% all_inpatient_cats) %>% 
  summarise(total_episodes = sum(episodes)) %>% 
  ggplot(aes(x = quarter, y = total_episodes, colour = admission_type)) +
  geom_line(aes(group = admission_type)) +
  geom_point() +
  theme_classic() +
  scale_y_continuous(labels = scales::comma, expand = c(0,0), limits = c(0,NA)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title = "Total admissions for Inpatients",
       x = "Quarter",
       y = "Total Episodes",
       col = "Admission Type")

specialties %>% 
  distinct(admission_type, specialty_name)

specialties %>% 
  group_by(quarter, admission_type, specialty_name) %>% 
  filter(admission_type == "Emergency Inpatients") %>% 
  summarise(total_episodes = sum(episodes)) %>% 
  ggplot(aes(x = quarter, y = total_episodes, colour = specialty_name)) +
  geom_line(aes(group = specialty_name)) +
  geom_point() +
  theme_classic() +
  scale_y_continuous(labels = scales::comma, expand = c(0,0), limits = c(0,10000)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title = "Total admissions for Emergency Inpatients",
       subtitle = "Split by specialty",
       x = "Quarter",
       y = "Total Episodes",
       col = "Admission Type")

Which departments changed the most between Covid and pre-covid


total_admissions <- specialties %>% 
  group_by(is_covid_year) %>% 
  filter(admission_type == "All Inpatients and Day cases") %>% 
  summarise(total_admissions = sum(episodes)) %>% 
  pull(total_admissions)

change_in_at_specialties <- specialties %>% 
  filter(admission_type %in% c(all_inpatient_cats, "All Day cases")) %>% 
  group_by(admission_type, specialty_name, is_covid_year) %>% 
  summarise(total_episodes = sum(episodes)) %>% 
  pivot_wider(names_from = is_covid_year, values_from = total_episodes) %>% 
  rename("covid_year" = "TRUE", "pre_covid_year" = "FALSE") %>% 
  mutate(pre_covid_year_prop = pre_covid_year / total_admissions[1],
         covid_year_prop = covid_year / total_admissions[2],
         percentage_change = ((covid_year_prop / pre_covid_year_prop) - 1) * 100) %>% 
  ungroup()

specialties %>% 
  filter(admission_type == "All Day cases" & specialty_name == "Cardiothoracic Surgery") %>% 
  group_by(is_covid_year) %>% 
  summarise(count = sum(episodes))
# top 5 changes in specialty proportion
change_in_at_specialties %>% 
  slice_max(percentage_change, n = 5)

# sort by largest proportion, top 5
change_in_at_specialties %>% 
  slice_max(percentage_change, n = 5) %>% 
  arrange(desc(covid_year_prop))

change_in_at_specialties %>% 
  filter(covid_year > 1000) %>% 
  slice_max(percentage_change, n = 5) %>% 
  mutate(label = str_c(specialty_name, "\n(", admission_type, ")")) %>% 
  ggplot(aes(x = reorder(label, sort(percentage_change)),
                         y = percentage_change)) +
  geom_col() +
  theme_classic() +
  scale_y_continuous(expand = c(0,0)) +
  theme(axis.title.x = element_blank(),
        axis.text.x = element_text(size = 8)) +
  labs(y = "Percentage Increase (%)",
       title = "Top 5 increases in hospital admissions (by specialty and admission type)",
       subtitle = "More than 1,000 admissions")

change_in_specialties <- specialties %>% 
  group_by(specialty_name, is_covid_year) %>% 
  summarise(total_episodes = sum(episodes)) %>% 
  pivot_wider(names_from = is_covid_year, values_from = total_episodes) %>% 
  rename("covid_year" = "TRUE", "pre_covid_year" = "FALSE") %>% 
  mutate(pre_covid_year_prop = pre_covid_year / total_admissions[1],
         covid_year_prop = covid_year / total_admissions[2],
         percentage_change = ((covid_year_prop / pre_covid_year_prop) - 1) * 100) %>% 
  ungroup()

change_in_specialties %>% 
  slice_max(percentage_change, n = 5) %>% 
  filter(percentage_change > 0) %>% 
  arrange(desc(percentage_change)) %>% 
  ggplot(aes(x = reorder(specialty_name, percentage_change, decreasing = TRUE),
             y = percentage_change)) +
  geom_col() +
  theme_classic() +
  scale_y_continuous(expand = c(0,0)) +
  theme(axis.title.x = element_blank(),
        axis.text.x = element_text(size = 8)) +
  labs(y = "Percentage Increase (%)",
       title = "Top 5 changes in hospital admissions (by specialty) - pre-Covid vs Covid",
       subtitle = "More than 1,000 admissions")


wt_with_discharges <- waiting_times_raw %>% 
  mutate(date_ym = ym(month), .before = month,
         month = month(date_ym, label = TRUE, abbr = FALSE),
         year = year(date_ym)) %>% 
  left_join(hb, c("hbt" = "hb")) %>% 
  left_join(hospitals, c("treatment_location" = "location")) %>% 
  rename(total_attendance = number_of_attendances_aggregate,
         wait_lt_4hrs = number_meeting_target_aggregate,
         wait_gt_8hrs = attendance_greater8hrs,
         wait_gt_12hrs = attendance_greater12hrs,
         health_board = hb_name,
         hospital_id = treatment_location, 
         hospital_name = location_name) %>% 
  select(-ends_with("qf")) %>% 
  select(date_ym, year, month, health_board, hospital_id, hospital_name,
         everything(), -country, - hbt)

# check if there is a trend across all years
wt_with_discharges %>% 
  group_by(date_ym, hospital_name) %>% 
  summarise(transfers = sum(discharge_destination_transfer, na.rm = TRUE)) %>% 
  ggplot(aes(x = date_ym, y = transfers, col = hospital_name)) +
  geom_line() +
  theme(legend.position = "none")

# check if there is a seasonal trend
wt_with_discharges %>% 
  mutate(month = factor(month, levels = c("July", "August", "September", "October", "November", "December", "January", "February", "March", "April", "May", "June"))) %>% 
  group_by(month, health_board) %>% 
  summarise(transfers = sum(discharge_destination_other_specialty, na.rm = TRUE)) %>% 
  ggplot(aes(x = month, y = transfers, group = health_board, col = health_board)) +
  geom_line() +
  theme(legend.position = "none") +
  facet_wrap(~ health_board, scales = "free_y") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Bed occupancy data


beds_raw <- read_csv(here("raw_data/non_covid/beds_by_nhs_board_of_treatment_and_specialty.csv")) %>% 
  clean_names() %>% 
  select(-ends_with("qf")) 
# all specialty names
beds_raw %>% 
  group_by(specialty_name) %>% 
  summarise(sum(all_staffed_beddays))

beds_raw %>% 
  filter(specialty_name != "All Acute" & specialty_name != "All Specialties") %>% 
  # group_by(specialty_name) %>% 
  summarise(sum(all_staffed_beddays))
# 209139660


beds <- beds_raw %>% 
  left_join(hb, "hb") %>% 
  left_join(hospitals, "location") %>% 
  select(quarter, hb, hb_name, location, location_name, specialty_name:percentage_occupancy) %>% 
  mutate()

beds %>% 
  group_by(quarter) %>% 
  summarise(staffed_beds = sum(all_staffed_beddays),
            occupied_beds = sum(total_occupied_beddays), 
            occupation_percentage = occupied_beds / staffed_beds * 100) %>% 
  ggplot(aes(x = quarter, y = occupation_percentage, group = 1)) +
  geom_line()

Wait times - baseline (pre-covid vs covid)

Percentage of wait times within target (<4hrs)


# pre-covid <= 2019, covid => 2020

avg_wt_target_pre_covid <- waiting_times %>% 
  filter(year <= 2019) %>% 
  group_by(month) %>% 
  summarise(total_attendance = sum(total_attendance),
            total_wait_lt_4hrs = sum(wait_lt_4hrs),
            target_wait_prop = total_wait_lt_4hrs / total_attendance)

avg_wt_target_pre_covid %>% 
  ggplot(aes(x = month, y = target_wait_prop, group = 1)) +
  geom_line() +
  geom_smooth(se = 0)

waiting_times %>% 
  filter(year >= 2020) %>%
  group_by(year, month) %>% 
  summarise(total_attendance = sum(total_attendance),
            total_wait_lt_4hrs = sum(wait_lt_4hrs),
            target_wait_prop = total_wait_lt_4hrs / total_attendance) %>% 
  ggplot(aes(x = month, y = target_wait_prop,
                group = factor(year), col = factor(year))) +
  geom_line() +
  geom_point() +
  geom_line(data = avg_wt_target_pre_covid, aes(x = month, y = target_wait_prop,
                                                group = 1, colour = "Baseline"),
              size = 1) +
  geom_point(data = avg_wt_target_pre_covid, aes(x = month, y = target_wait_prop,
                                                group = 1, colour = "Baseline")) +
  theme_classic() +
  scale_color_manual(name = "Year", values = c("Baseline" = "darkblue",
                                               "2020" = "red",
                                               "2021" = "green",
                                               "2022" = "orange")) +
  scale_y_continuous(labels = scales::percent) +
  labs(y = "Percentage of admissions (%)",
       title = "Proportion of waiting times greater than 12 hours",
       subtitle = "Pre-covid (2007-2019) vs covid (2020+)",
       col = "Year") +
  theme(axis.title.x = element_blank(),
        axis.text.x = element_text(angle = 45, hjust = 1))

Percentage of wait times >8hrs


avg_wt_gt_8hrs_pre_covid <- waiting_times %>% 
  filter(year <= 2019) %>% 
  group_by(month) %>% 
  summarise(total_attendance = sum(total_attendance),
            total_wait_gt_8hrs = sum(wait_gt_8hrs),
            target_wait_prop = total_wait_gt_8hrs / total_attendance)

avg_wt_gt_8hrs_pre_covid %>% 
  ggplot(aes(x = month, y = target_wait_prop, group = 1)) +
  geom_line() +
  geom_smooth(se = 0)

waiting_times %>% 
  filter(year >= 2020) %>%
  group_by(year, month) %>% 
  summarise(total_attendance = sum(total_attendance),
            total_wait_gt_8hrs = sum(wait_gt_8hrs),
            target_wait_prop = total_wait_gt_8hrs / total_attendance) %>% 
  ggplot(aes(x = month, y = target_wait_prop,
                group = factor(year), col = factor(year))) +
  geom_line() +
  geom_point() +
  geom_line(data = avg_wt_gt_8hrs_pre_covid, aes(x = month, y = target_wait_prop,
                                                group = 1, colour = "Baseline"),
              size = 1) +
    geom_point(data = avg_wt_gt_8hrs_pre_covid, aes(x = month, y = target_wait_prop,
                                                group = 1, colour = "Baseline")) +
  theme_classic() +
  scale_color_manual(name = "Year", values = c("Baseline" = "darkblue", "2020" = "red", "2021" = "green", "2022" = "orange")) +
  scale_y_continuous(labels = scales::percent) +
  labs(y = "Percentage of admissions (%)",
       title = "Proportion of waiting times greater than 8 hours",
       subtitle = "Pre-covid (2007-2019) vs covid (2020+)",
       col = "Year") +
  theme(axis.title.x = element_blank(),
        axis.text.x = element_text(angle = 45, hjust = 1))

Percentage of wait times >12hrs


avg_wt_gt_12hrs_pre_covid <- waiting_times %>% 
  filter(year <= 2019) %>% 
  group_by(month) %>% 
  summarise(total_attendance = sum(total_attendance),
            total_wait_gt_12hrs = sum(wait_gt_12hrs),
            target_wait_prop = total_wait_gt_12hrs / total_attendance)

avg_wt_gt_12hrs_pre_covid %>% 
  ggplot(aes(x = month, y = target_wait_prop, group = 1)) +
  geom_line() +
  geom_smooth(se = 0)

waiting_times %>% 
  filter(year >= 2020) %>%
  group_by(year, month) %>% 
  summarise(total_attendance = sum(total_attendance),
            total_wait_gt_12hrs = sum(wait_gt_12hrs),
            target_wait_prop = total_wait_gt_12hrs / total_attendance) %>% 
  ggplot(aes(x = month, y = target_wait_prop,
                group = factor(year), col = factor(year))) +
  geom_line() +
  geom_point() +
  geom_line(data = avg_wt_gt_12hrs_pre_covid, aes(x = month, y = target_wait_prop,
                                                group = 1, colour = "Baseline"),
              size = 1) +
    geom_point(data = avg_wt_gt_12hrs_pre_covid, aes(x = month, y = target_wait_prop,
                                                group = 1, colour = "Baseline")) +
  theme_classic() +
  scale_color_manual(name = "Year", values = c("Baseline" = "darkblue",
                                               "2020" = "red",
                                               "2021" = "green",
                                               "2022" = "orange")) +
  scale_y_continuous(labels = scales::percent) +
  labs(y = "Percentage of admissions (%)",
       title = "Proportion of waiting times greater than 12 hours",
       subtitle = "Pre-covid (2007-2019) vs covid (2020+)",
       col = "Year") +
  theme(axis.title.x = element_blank(),
        axis.text.x = element_text(angle = 45, hjust = 1))

Jack’s question:


beds_treatment_specialty <- beds


df1 <- beds_treatment_specialty %>% #pre covid dates, all health baords
  mutate(date = yq(quarter), month = month(date, label = TRUE, abbr = TRUE),
         year = year(date)) %>% 
  filter(year <= 2019, hb == "S08000015") %>% # hb selected by user input
  group_by(month) %>% 
  summarise(avg_occupancy = mean(percentage_occupancy, na.rm = TRUE))


df2 <- beds_treatment_specialty %>% 
  mutate(date = yq(quarter), month = month(date, label = TRUE, abbr = TRUE),
         year = year(date)) %>% 
  filter(year > 2019, hb == "S08000015") %>% #post covid, filter based on map input
  group_by(year, month) %>% 
  summarise(avg_occupancy = mean(percentage_occupancy, na.rm = TRUE))

## no longer required
# df3 <- df1 %>% 
#   mutate(Type = "baseline") %>% 
#   bind_rows(df2 %>% 
#               mutate(Type = "post-covid"))

df2 %>% 
  ggplot(aes(x = month, y = avg_occupancy, colour = factor(year), group = year)) +
  geom_point() +
  geom_line() +
  geom_line(data = df1, aes(x = month, y = avg_occupancy, group = 1, col = "Baseline")) +
  geom_point(data = df1, aes(x = month, y = avg_occupancy, group = 1, col = "Baseline")) +
  scale_color_manual(name = "Year", values = c("Baseline" = "darkblue",
                                               "2020" = "red",
                                               "2021" = "green")) +
  labs(title = "Avg Occupancy by Health Board vs Baseline", # need to update these
       x = "Month",
       y = "Avg Occupancy Rate")


df2_wide <- df2 %>% 
  pivot_wider(names_from = year, values_from = avg_occupancy)

df12 <- df1 %>% 
  rename(baseline = avg_occupancy) %>% 
  left_join(df2_wide, "month")

df12

df3 <- beds_treatment_specialty %>% #pre covid dates, all health baords
  mutate(date = yq(quarter), month = month(date, label = TRUE, abbr = TRUE),
         year = year(date)) %>% 
  filter(year <= 2019, hb == "S08000015") %>% # hb selected by user input
  group_by(month) %>% 
  summarise(total_available = sum(all_staffed_beddays), 
            total_occupied = sum(total_occupied_beddays),
            avg_occupancy = total_occupied / total_available)


df4 <- beds_treatment_specialty %>% 
  mutate(date = yq(quarter), month = month(date, label = TRUE, abbr = TRUE),
         year = year(date)) %>% 
  filter(year > 2019, hb == "S08000015") %>% #post covid, filter based on map input
  group_by(year, month) %>% 
  summarise(total_available = sum(all_staffed_beddays), 
            total_occupied = sum(total_occupied_beddays),
            avg_occupancy = total_occupied / total_available)

df4 %>% 
  ggplot(aes(x = month, y = avg_occupancy, colour = factor(year), group = year)) +
  geom_point() +
  geom_line() +
  geom_line(data = df3, aes(x = month, y = avg_occupancy, group = 1, col = "Baseline")) +
  geom_point(data = df3, aes(x = month, y = avg_occupancy, group = 1, col = "Baseline")) +
  scale_color_manual(name = "Year", values = c("Baseline" = "darkblue",
                                               "2020" = "red",
                                               "2021" = "green")) +
  labs(title = "Avg Occupancy by Health Board vs Baseline", # need to update these
       x = "Month",
       y = "Avg Occupancy Rate") +
  scale_y_continuous(labels = scales::percent)


df4_wide <- df2 %>% 
  pivot_wider(names_from = year, values_from = avg_occupancy)

df34 <- df3 %>% 
  rename(baseline = avg_occupancy) %>% 
  left_join(df2_wide, "month") %>% 
  select(-total_available, - total_occupied) %>% 
  mutate(baseline = baseline * 100)
# weighted average occupancy rate
df34
# average of occupancy percentages
df12

how does bed usage change over time


beds %>%
  group_by(quarter) %>%
  summarise(beds_available = sum(all_staffed_beddays),
            beds_occupied = sum(total_occupied_beddays)) %>%
  pivot_longer(beds_available:beds_occupied, names_to = "bed_type",
               values_to = "num_beds") %>% 
  ggplot(aes(x = quarter, y = num_beds, colour = bed_type, group = bed_type)) +
  geom_line() +
  scale_y_continuous(labels = scales::comma) +
  theme_classic() +
  theme(axis.text = element_text(angle = 45, hjust = 1),
        axis.title.x = element_blank()) +
  labs(y = "Number of bed days",
       title = "Number of beds available/occupied over time",
       col = "Bed Type")

bed use by specialty


beds %>%
  group_by(quarter, specialty_name) %>%
  # filter(specialty_name %in% c("Clinical Radiology", "Intensive Care Medicine")) %>% 
  summarise(beds_available = sum(all_staffed_beddays),
            beds_occupied = sum(total_occupied_beddays)) %>%
  pivot_longer(beds_available:beds_occupied, names_to = "bed_type",
               values_to = "num_beds") %>% 
  ggplot(aes(x = quarter, y = num_beds, colour = specialty_name, group = specialty_name)) +
  geom_line() +
  facet_wrap(~bed_type) +
  scale_y_continuous(labels = scales::comma) +
  theme_classic() +
  theme(axis.text = element_text(angle = 45, hjust = 1),
        axis.title.x = element_blank()) +
  labs(y = "Number of bed days",
       title = "Number of beds available/occupied over time",
       col = "Bed Type")

beds %>% 
  mutate(year = as.numeric(str_extract(quarter, "[0-9]{4}")),
    is_covid_year = case_when(
    year <= 2019 ~ FALSE,
    year >= 2020 ~ TRUE
    )) %>% 
  group_by(specialty_name, is_covid_year) %>% 
  summarise(beds_available = sum(all_staffed_beddays),
            beds_occupied = sum(total_occupied_beddays)) %>% 
  select(specialty_name, is_covid_year, beds_occupied) %>%  
  pivot_wider(names_from = is_covid_year, values_from = beds_occupied) %>% 
  rename("pre_covid" = "FALSE", "covid" = "TRUE") %>% 
  drop_na() %>% 
  mutate(diff_occupied = covid - pre_covid,
         diff_occupied_pc = ((covid / pre_covid) - 1) * 100) %>% 
  filter(diff_occupied_pc > 0) %>% 
  arrange(desc(diff_occupied_pc))
  

waiting times

cleaning


hb <- read_csv(here("clean_data/hb_list_simple.csv"))

waiting_times <- waiting_times_raw %>% 
  mutate(date_ym = ym(month), .before = month,
         month = month(date_ym, label = TRUE, abbr = FALSE),
         year = year(date_ym)) %>% 
  left_join(hb, c("hbt" = "hb")) %>% 
  left_join(hospitals, c("treatment_location" = "location")) %>% 
  rename(total_attendance = number_of_attendances_aggregate,
         wait_lt_4hrs = number_meeting_target_aggregate,
         wait_gt_8hrs = attendance_greater8hrs,
         wait_gt_12hrs = attendance_greater12hrs,
         hospital_id = treatment_location, 
         hospital_name = location_name) %>% 
  select(date_ym, year, month, hb_name, hospital_id, hospital_name, department_type,
         total_attendance, wait_lt_4hrs, wait_gt_8hrs, wait_gt_12hrs) %>% 
  mutate(wait_gt_4hrs = total_attendance - wait_lt_4hrs, .after = wait_lt_4hrs) %>%
  mutate(across(total_attendance:wait_gt_12hrs, .fns = ~coalesce(., 0)))

analysis


waiting_times %>% 
  mutate(is_covid_year = case_when(
    year <= 2019 ~ FALSE,
    year >= 2020 ~ TRUE
  )) %>% 
  group_by(is_covid_year) %>% 
  summarise(sum_attendance = sum(total_attendance), 
            wait_target = sum(wait_lt_4hrs)) %>% 
  pivot_longer(wait_target, names_to = "wait_time", values_to = "value") %>% 
  mutate(proportion = value / sum_attendance) %>% 
  ggplot(aes(ymax = proportion, ymin = 0, xmax = 2, xmin = 1, fill = proportion)) +
  geom_rect(aes(ymax = 1, ymin = 0, xmax = 2, xmin = 1), fill = "grey80") +
  geom_rect() + 
  coord_polar(theta = "y",start=-pi/2) + xlim(c(0, 2)) + ylim(c(0,2)) +
  geom_text(aes(x = 0, y = 0, label = scales::percent(proportion, accuracy = 0.1)), size = 6.5) +
  geom_text(aes(x = 0.5, y = 1.5), label = c("Pre-Covid", "During Covid"), family="Poppins Light", size=4.2) + 
  facet_wrap(~is_covid_year, nrow = 1) +
  theme_void() +
  # scale_fill_manual(values = c("red"="#C9146C", "orange"="#DA9112", "green"="#129188")) +
  scale_colour_manual(values = c("red"="#C9146C", "orange"="#DA9112", "green"="#129188")) +
  theme(strip.background = element_blank(),
        strip.text.x = element_blank(),
        legend.position = "none") +
# ,
#          +
  labs(title = "   Percentage of admissions achieving target wait times (<4hrs)")

library(ggforce)
library(scales)

waiting_times %>% 
  mutate(is_covid_year = case_when(
    year <= 2019 ~ FALSE,
    year >= 2020 ~ TRUE
  )) %>% 
  group_by(is_covid_year) %>% 
  summarise(sum_attendance = sum(total_attendance), 
            wait_target = sum(wait_lt_4hrs)) %>% 
  pivot_longer(wait_target, names_to = "wait_time", values_to = "value") %>% 
  mutate(proportion = value / sum_attendance) %>%
  mutate(ymin = rescale(0, to = pi*c(-.5,.5), from = 0:1), 
         ymax = rescale(proportion, to = pi*c(-.5,.5), from = 0:1)) %>%
  ggplot(aes(x0 = 0, y0 = 0, r0 = .5, r = 1)) + 
  geom_arc_bar(aes(start = - pi / 2, end = pi / 2), fill = "grey80") +
  geom_arc_bar(aes(x0 = 0, y0 = 0, r0 = .5, r = 1, start = ymin, end = ymax, fill = proportion)) +
  coord_fixed() +
  facet_wrap(~ is_covid_year) +
  ylim(-0.3, 1) +
  geom_text(aes(x = 0, y = 0.01, label = scales::percent(proportion, accuracy = 0.1)), size = 6.5) +
  geom_text(aes(x = 0, y = -0.25), label = c("Pre-Covid", "During Covid"), family= "Poppins Light", size=4.2) +
  theme_void() +
    theme(strip.background = element_blank(),
          strip.text = element_blank(),
        legend.position = "none",
        title = element_text(vjust = 1),
          plot.margin = unit(c(0, 0, 0, 0), "cm")) +
  labs(title = "   Percentage of admissions achieving target wait times (<4hrs)\n")

  

Colour palette


pal <- c(rgb(199, 175, 117, maxColorValue = 255),
         rgb(124, 36, 24, maxColorValue = 255), 
         rgb(210, 221, 213, maxColorValue = 255), 
         rgb(168, 106, 57, maxColorValue = 255), 
         rgb(222, 224, 227, maxColorValue = 255),
         rgb(186, 158, 53, maxColorValue = 255), 
         rgb(6, 57, 83, maxColorValue = 255), 
         rgb(109, 67, 85, maxColorValue = 255)
)

show_col(pal)

Rob’s problem

 inpatient_and_daycase_by_nhs_board_of_treatment_and_simd_non_covid_cleaned %>%
  select(quarter_year, year, hb_name, simd, admission_type, stays, is_covid_year) %>%
  filter(stays >0) %>%
  filter(hb_name != “”) %>%
Error: unexpected input in:
"  filter(stays >0) %>%
  filter(hb_name != “"
health_board_map %>%
  plot_geo(locationmode = "Scotland") %>% 
  add_trace(text = ~hb_name)
No scattergeo mode specifed:
  Setting the mode to markers
  Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
No scattergeo mode specifed:
  Setting the mode to markers
  Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIExvYWQgaW4gbGlicmFyaWVzDQpgYGB7cn0NCg0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KGphbml0b3IpDQpsaWJyYXJ5KHRzaWJibGUpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoc2YpDQoNCmBgYA0KIyBMb2FkIGluIGRhdGEgc2V0cw0KYGBge3J9DQoNCndhaXRpbmdfdGltZXNfcmF3IDwtIHJlYWRfY3N2KGhlcmUoInJhd19kYXRhL25vbl9jb3ZpZC9tb250aGx5X2FlX3dhaXRpbmd0aW1lc18yMDIyMDYuY3N2IikpICU+JSANCiAgY2xlYW5fbmFtZXMoKQ0KDQpoYiA8LSByZWFkX2NzdihoZXJlKCJjbGVhbl9kYXRhL2hiX2xpc3Rfc2ltcGxlLmNzdiIpKQ0KDQpob3NwaXRhbHMgPC0gcmVhZF9jc3YoaGVyZSgicmF3X2RhdGEvZ2VuZXJhbC9jdXJyZW50LWhvc3BpdGFsX2ZsYWdnZWQyMDIxMTIxNi5jc3YiKSkgJT4lIA0KICBjbGVhbl9uYW1lcygpICU+JSANCiAgc2VsZWN0KGxvY2F0aW9uLCBsb2NhdGlvbl9uYW1lKQ0KDQpgYGANCg0KIyBjbGVhbiBkYXRhc2V0DQoNClRoZSBmb2xsb3dpbmcgY2xlYW5pbmcgZG9lcyB0aGUgZm9sbG93aW5nIHRvIHRoZSB3YWl0aW5nIHRpbWVzIGRhdGEgc2V0OiANCi0gY29udmVydHMgbW9udGggY29sdW1uIHRvIHllYXJfbW9udGggZGF0ZXMgYW5kIGV4dHJhY3RzIHllYXJzIGFuZCBtb250aHMgIA0KLSBqb2lucyBoZWFsdGggYm9hcmQgYW5kIGhvc3BpdGFsIG5hbWVzIHRvIGRhdGEgc2V0ICANCi0gcmVuYW1lcyBjb2x1bW5zIHRvIG1vcmUgZWFzaWx5IHVuZGVyc3RhbmRhYmxlIG5hbWVzICANCi0gcmVtb3ZlcyBjb2x1bW5zIHJlbGF0aW5nIHRvICJlcGlzb2RlcyIsICJxdWFsaWZpZXIgY29kZXMiIGFuZCAiZGlzY2hhcmdlcyINCi0gYWRkcyBuZXcgdmFsdWUgb2Ygd2FpdCBncmVhdGVyIHRoYW4gNCBob3VycyB0byB0aGUgZGF0YSAgDQotIF9yZXBsYWNlcyBhbGwgTkEgdmFsdWVzIHdpdGggMCAodGhpcyBzdGVwIG1heSBiZSBvcHRpb25hbClfDQoNClBsZWFzZSBub3RlIHRoYXQgNCBob3VycyB3YWl0IHRpbWUgaXMgdGhlICJUYXJnZXQiIHdhaXQgdGltZSBmb3IgdGhlIE5IUyBhbmQgaXMNCnJlcHJlc2VudGVkIGJ5IHRoZSAid2FpdF9sdF80aHJzIiBjb2x1bW4gdmFsdWVzLg0KYGBge3J9DQojIGNsZWFuaW5nIHNjcmlwdA0Kd2FpdGluZ190aW1lcyA8LSB3YWl0aW5nX3RpbWVzX3JhdyAlPiUgDQogIG11dGF0ZShkYXRlX3ltID0geW0obW9udGgpLCAuYmVmb3JlID0gbW9udGgsDQogICAgICAgICBtb250aCA9IG1vbnRoKGRhdGVfeW0sIGxhYmVsID0gVFJVRSwgYWJiciA9IEZBTFNFKSwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGVfeW0pKSAlPiUgDQogIGxlZnRfam9pbihoYiwgYygiaGJ0IiA9ICJoYiIpKSAlPiUgDQogIGxlZnRfam9pbihob3NwaXRhbHMsIGMoInRyZWF0bWVudF9sb2NhdGlvbiIgPSAibG9jYXRpb24iKSkgJT4lIA0KICByZW5hbWUodG90YWxfYXR0ZW5kYW5jZSA9IG51bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUsDQogICAgICAgICB3YWl0X2x0XzRocnMgPSBudW1iZXJfbWVldGluZ190YXJnZXRfYWdncmVnYXRlLA0KICAgICAgICAgd2FpdF9ndF84aHJzID0gYXR0ZW5kYW5jZV9ncmVhdGVyOGhycywNCiAgICAgICAgIHdhaXRfZ3RfMTJocnMgPSBhdHRlbmRhbmNlX2dyZWF0ZXIxMmhycywNCiAgICAgICAgIGhvc3BpdGFsX2lkID0gdHJlYXRtZW50X2xvY2F0aW9uLCANCiAgICAgICAgIGhvc3BpdGFsX25hbWUgPSBsb2NhdGlvbl9uYW1lKSAlPiUNCiAgc2VsZWN0KGRhdGVfeW0sIHllYXIsIG1vbnRoLCBoYl9uYW1lLCBob3NwaXRhbF9pZCwgaG9zcGl0YWxfbmFtZSwgZGVwYXJ0bWVudF90eXBlLA0KICAgICAgICAgdG90YWxfYXR0ZW5kYW5jZSwgd2FpdF9sdF80aHJzLCB3YWl0X2d0XzhocnMsIHdhaXRfZ3RfMTJocnMpICU+JSANCiAgbXV0YXRlKHdhaXRfZ3RfNGhycyA9IHRvdGFsX2F0dGVuZGFuY2UgLSB3YWl0X2x0XzRocnMsIC5hZnRlciA9IHdhaXRfbHRfNGhycykgJT4lDQogIG11dGF0ZShhY3Jvc3ModG90YWxfYXR0ZW5kYW5jZTp3YWl0X2d0XzEyaHJzLCAuZm5zID0gfmNvYWxlc2NlKC4sIDApKSkNCg0Kd2FpdGluZ190aW1lcyA8LSByZWFkX2NzdihoZXJlKCJjbGVhbl9kYXRhL3dhaXRfdGltZXMuY3N2IikpICU+JSANCiAgbXV0YXRlKG1vbnRoID0gbW9udGgoZGF0ZV95bSwgbGFiZWwgPSBUUlVFLCBhYmJyID0gRkFMU0UpKSANCmBgYA0KDQpgYGB7cn0NCiMgY3JlYXRlIHRhYmxlIHdpdGggcHJvcG9ydGlvbnMgb2Ygd2FpdCB0aW1lcyB1c2VkIGZvciB0aGUgYW5hbHlzaXMNCndhaXRpbmdfdGltZXNfcHJvcCA8LSB3YWl0aW5nX3RpbWVzICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbnRhaW5zKCJ3YWl0IiksIG5hbWVzX3RvID0gIndhaXRfY2F0ZWdvcnkiLCB2YWx1ZXNfdG8gPSAibnVtYmVyX29mX2F0dGVuZGFuY2VzIikgJT4lIA0KICBtdXRhdGUod2FpdF9wcm9wID0gbnVtYmVyX29mX2F0dGVuZGFuY2VzIC8gdG90YWxfYXR0ZW5kYW5jZSwNCiAgICAgICAgIHdhaXRfY2F0ZWdvcnkgPSBzdHJfcmVwbGFjZSh3YWl0X2NhdGVnb3J5LCAid2FpdCIsICJwcm9wIikpICU+JSANCiAgc2VsZWN0KC1udW1iZXJfb2ZfYXR0ZW5kYW5jZXMpICU+JSANCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHdhaXRfY2F0ZWdvcnksIHZhbHVlc19mcm9tID0gd2FpdF9wcm9wKQ0KDQoNCndhaXRpbmdfdGltZXNfcHJvcA0KYGBgDQoNCiMgQW5hbHlzaXMNCg0KIyMgSG93IGRvZXMgaG9zcGl0YWwgYXR0ZW5kYW5jZXMgY2hhbmdlIHdpdGggdGltZT8NCg0KYGBge3J9DQojIHBsb3QgYWxsIGRhdGEgLSBhdHRlbmRhbmNlcyBwZXIgeWVhcg0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHRvdGFsX2F0dGVuZGFuY2UpKSArDQogIGdlb21fbGluZSgpDQoNCiMgYXR0ZW5kYW5jZXMgLSBhbGwgZGF0YSBjb3ZpZCBzZWFzb25hbCBhbmFseXNpcw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIsIG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdG90YWxfYXR0ZW5kYW5jZSwgZ3JvdXAgPSB5ZWFyLCBjb2wgPSBmYWN0b3IoeWVhcikpKSArDQogIGdlb21fbGluZSgpDQoNCiMgYXR0ZW5kYW5jZXMgcGVyIG1vbnRoIC0gcHJlLWNvdmlkIHNlYXNvbmFsIGFuYWx5c2lzDQp3YWl0aW5nX3RpbWVzICU+JSANCiAgZmlsdGVyKHllYXIgPCAyMDIwKSAlPiUgDQogIGdyb3VwX2J5KHllYXIsIG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdG90YWxfYXR0ZW5kYW5jZSwgZ3JvdXAgPSB5ZWFyLCBjb2wgPSBmYWN0b3IoeWVhcikpKSArDQogIGdlb21fbGluZSgpDQoNCiMgYXR0ZW5kYW5jZXMgcGVyIG1vbnRoIC0gY292aWQgc2Vhc29uYWwgYW5hbHlzaXMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBmaWx0ZXIoeWVhciA+PSAyMDIwKSAlPiUgDQogIGdyb3VwX2J5KHllYXIsIG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdG90YWxfYXR0ZW5kYW5jZSwgZ3JvdXAgPSB5ZWFyLCBjb2wgPSBmYWN0b3IoeWVhcikpKSArDQogIGdlb21fbGluZSgpDQoNCmBgYA0KDQpgYGB7cn0NCg0KaGVhbHRoX2JvYXJkX2lucHV0IDwtIGMoIkJvcmRlcnMiLCAiTG90aGlhbiIsICJBeXJzaGlyZSBhbmQgQXJyYW4iLCAiRHVtZnJpZXMgYW5kIEdhbGxvd2F5IikNCg0KIyBoZWFsdGhfYm9hcmRfaW5wdXQgPC0gaGIkaGJfbmFtZQ0KDQpwYXN0ZSgiTXVsdGlwbGUgSEI6XG4iLCBwYXN0ZShzb3J0KGhlYWx0aF9ib2FyZF9pbnB1dCksIGNvbGxhcHNlID0gIiwgIiksIHNlcCA9ICJcbiIpDQoNCnN0cl9jKCJNdWx0aXBsZSBIQnM6XG4iLCBzdHJfYygiQm9yZGVycyIsICJMb3RoaWFuIiwgIkR1bWZyaWVzIiwgc2VwID0gIixcbiIpKQ0KDQojIHBsb3QgYWxsIGRhdGEgLSBhdHRlbmRhbmNlcyBwZXIgeWVhcg0KDQogIA0KICBpZihsZW5ndGgoaGVhbHRoX2JvYXJkX2lucHV0KSA8PSAzKSB7DQogICANCiAgICAjZmlyc3QgdHdvIHJvd3Mgd2lsbCBiZSBmcm9tIHJlYWN0aXZlIGZ1bmN0aW9uDQogICAgcCA8LSB3YWl0aW5nX3RpbWVzICU+JSANCiAgICAgIGZpbHRlcihoYl9uYW1lICVpbiUgaGVhbHRoX2JvYXJkX2lucHV0KSAlPiUgDQogICAgICBncm91cF9ieShkYXRlX3ltLCBoYl9uYW1lKSAlPiUgDQogICAgICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgJT4lIA0KICAgICAgZ2dwbG90KGFlcyh4ID0gZGF0ZV95bSwgeSA9IHRvdGFsX2F0dGVuZGFuY2UsIGNvbCA9IGhiX25hbWUpKSArDQogICAgICBnZW9tX2xpbmUoKQ0KDQogIH0gZWxzZSB7DQogICAgDQogICAgaWYobGVuZ3RoKGhlYWx0aF9ib2FyZF9pbnB1dCkgPT0gMTQpIHsNCiAgICAgIGhiX2xhYmVsIDwtICJBbGwgSGVhbHRoIEJvYXJkcyINCiAgICB9IGVsc2Ugew0KICAgICAgaGJfbGFiZWwgPC0gc3RyX2MoIlRvdGFsIG9mIE11bHRpcGxlIEhCczpcbiIsDQogICAgICAgICAgICAgICAgICAgICAgICBzdHJfYyhoZWFsdGhfYm9hcmRfaW5wdXQsIGNvbGxhcHNlID0gIixcbiIpKQ0KICAgIH0NCiANCiAgICBwIDwtIHdhaXRpbmdfdGltZXMgJT4lIA0KICAgICAgZmlsdGVyKGhiX25hbWUgJWluJSBoZWFsdGhfYm9hcmRfaW5wdXQpICU+JSANCiAgICAgIG11dGF0ZShoYl9sYWJlbCA9IGhiX2xhYmVsKSAlPiUgDQogICAgICBncm91cF9ieShkYXRlX3ltKSAlPiUgDQogICAgICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgJT4lIA0KICAgICAgZ2dwbG90KGFlcyh4ID0gZGF0ZV95bSwgeSA9IHRvdGFsX2F0dGVuZGFuY2UsIGNvbG91ciA9IGhiX2xhYmVsKSkgKw0KICAgICAgZ2VvbV9saW5lKCkNCiAgICANCiAgfQ0KDQpwICArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBjb21tYSwgDQogICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKDAsIDApLA0KICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLCBOQSkpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiVZIiwNCiAgICAgICAgICAgICAgIGRhdGVfYnJlYWtzID0gIjEgeWVhciIpICsNCiAgbGFicyh0aXRsZSA9ICJUb3RhbCBob3NwaXRhbCBhdHRlbmRhbmNlcyIsDQogICAgICAgc3VidGl0bGUgPSAiSnVseSAyMDA3IHRvIEp1bmUgMjAyMiIsIA0KICAgICAgIGNvbCA9ICJIZWFsdGggQm9hcmQiLA0KICAgICAgIHkgPSAiVG90YWwgYXR0ZW5kYW5jZXMiKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgbGVnZW5kLnRleHQuYWxpZ24gPSAwKQ0KDQpgYGANCg0KDQojIEhvdyBkbyB3YWl0IHRpbWVzIGNoYW5nZSBwZXIgeWVhcj8gKGluIHRlcm1zIG9mIG51bWJlcnMpDQoNCmBgYHtyfQ0KIyB3YWl0IHRpbWVzIGxlc3MgdGhhbiA0IGhvdXJzDQp3YWl0aW5nX3RpbWVzICU+JSANCiAgZ3JvdXBfYnkoeWVhcikgJT4lIA0KICBzdW1tYXJpc2Uod2FpdF9sdF80aHJzID0gc3VtKHdhaXRfbHRfNGhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHdhaXRfbHRfNGhycykpICsNCiAgZ2VvbV9jb2woKQ0KDQojIHdhaXQgdGltZXMgbW9yZSB0aGFuIDQgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyKSAlPiUgDQogIHN1bW1hcmlzZSh3YWl0X2d0XzRocnMgPSBzdW0od2FpdF9ndF80aHJzKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gd2FpdF9ndF80aHJzKSkgKw0KICBnZW9tX2NvbCgpDQoNCiMgd2FpdCB0aW1lcyBtb3JlIHRoYW4gOCBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIpICU+JSANCiAgc3VtbWFyaXNlKHdhaXRfZ3RfOGhycyA9IHN1bSh3YWl0X2d0XzhocnMpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSB3YWl0X2d0XzhocnMpKSArDQogIGdlb21fY29sKCkNCg0KIyB3YWl0IHRpbWVzIG1vcmUgdGhhbiAxMiBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIpICU+JSANCiAgc3VtbWFyaXNlKHdhaXRfZ3RfMTJocnMgPSBzdW0od2FpdF9ndF8xMmhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHdhaXRfZ3RfMTJocnMpKSArDQogIGdlb21fY29sKCkNCg0KYGBgDQoNCiMgSG93IGRvIHdhaXQgdGltZXMgY2hhbmdlIHBlciB5ZWFyPyAoaW4gdGVybXMgb2YgcHJvcG9ydGlvbikNCg0KYGBge3J9DQoNCiMgd2FpdCB0aW1lcyBsZXNzIHRoYW4gNCBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICB3YWl0X2x0XzRocnMgPSBzdW0od2FpdF9sdF80aHJzKSwNCiAgICAgICAgICAgIHByb3BfbHRfNGhycyA9IHdhaXRfbHRfNGhycyAvIHRvdGFsX2F0dGVuZGFuY2UpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHByb3BfbHRfNGhycykpICsNCiAgZ2VvbV9jb2woKQ0KDQojIHdhaXQgdGltZXMgbW9yZSB0aGFuIDQgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgd2FpdF9ndF80aHJzID0gc3VtKHdhaXRfZ3RfNGhycyksDQogICAgICAgICAgICBwcm9wX2d0XzRocnMgPSB3YWl0X2d0XzRocnMgLyB0b3RhbF9hdHRlbmRhbmNlKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBwcm9wX2d0XzRocnMpKSArDQogIGdlb21fY29sKCkNCg0KIyB3YWl0IHRpbWVzIG1vcmUgdGhhbiA4IGhvdXJzDQp3YWl0aW5nX3RpbWVzICU+JSANCiAgZ3JvdXBfYnkoeWVhcikgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHdhaXRfZ3RfOGhycyA9IHN1bSh3YWl0X2d0XzhocnMpLA0KICAgICAgICAgICAgcHJvcF9ndF84aHJzID0gd2FpdF9ndF84aHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcHJvcF9ndF84aHJzKSkgKw0KICBnZW9tX2NvbCgpDQoNCiMgd2FpdCB0aW1lcyBtb3JlIHRoYW4gMTIgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgd2FpdF9ndF8xMmhycyA9IHN1bSh3YWl0X2d0XzEyaHJzKSwNCiAgICAgICAgICAgIHByb3BfZ3RfMTJocnMgPSB3YWl0X2d0XzEyaHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcHJvcF9ndF8xMmhycykpICsNCiAgZ2VvbV9jb2woKSArDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsMCksDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIGxhYnMoeSA9ICJQZXJjZW50YWdlIG9mIGF0dGVuZGFuY2VzIGdyZWF0ZXIgdGhhbiAxMiBob3VycyIsDQogICAgICAgdGl0bGUgPSAiV2FpdCB0aW1lcyBvZiA+MTJob3VycyBlYWNoIHllYXIiKQ0KDQpgYGANCiMgSG93IGRvIHdhaXQgdGltZXMgZGlmZmVyIGJldHdlZW4gZGVwYXJ0bWVudHM/IChpbiB0ZXJtcyBvZiBwcm9wb3J0aW9ucykNCg0KYGBge3J9DQoNCiMgd2FpdCB0aW1lcyBsZXNzIHRoYW4gNCBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIsIGRlcGFydG1lbnRfdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHdhaXRfbHRfNGhycyA9IHN1bSh3YWl0X2x0XzRocnMpLA0KICAgICAgICAgICAgcHJvcF9sdF80aHJzID0gd2FpdF9sdF80aHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcHJvcF9sdF80aHJzLCBmaWxsID0gZGVwYXJ0bWVudF90eXBlKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQoNCiMgd2FpdCB0aW1lcyBtb3JlIHRoYW4gNCBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIsIGRlcGFydG1lbnRfdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHdhaXRfZ3RfNGhycyA9IHN1bSh3YWl0X2d0XzRocnMpLA0KICAgICAgICAgICAgcHJvcF9ndF80aHJzID0gd2FpdF9ndF80aHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcHJvcF9ndF80aHJzLCBmaWxsID0gZGVwYXJ0bWVudF90eXBlKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQoNCiMgd2FpdCB0aW1lcyBtb3JlIHRoYW4gOCBob3Vycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KHllYXIsIGRlcGFydG1lbnRfdHlwZSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHdhaXRfZ3RfOGhycyA9IHN1bSh3YWl0X2d0XzhocnMpLA0KICAgICAgICAgICAgcHJvcF9ndF84aHJzID0gd2FpdF9ndF84aHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcHJvcF9ndF84aHJzLCBmaWxsID0gZGVwYXJ0bWVudF90eXBlKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQoNCiMgd2FpdCB0aW1lcyBtb3JlIHRoYW4gMTIgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyLCBkZXBhcnRtZW50X3R5cGUpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICB3YWl0X2d0XzEyaHJzID0gc3VtKHdhaXRfZ3RfMTJocnMpLA0KICAgICAgICAgICAgcHJvcF9ndF8xMmhycyA9IHdhaXRfZ3RfMTJocnMgLyB0b3RhbF9hdHRlbmRhbmNlKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBwcm9wX2d0XzEyaHJzLCBmaWxsID0gZGVwYXJ0bWVudF90eXBlKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpDQoNCmBgYA0KDQojIEhvdyBkbyB3YWl0IHRpbWVzIGNoYW5nZSBwZXIgeWVhciAmIG1vbnRoPyAoaW4gdGVybXMgb2YgbnVtYmVycykNCg0KYGBge3J9DQojIHdhaXQgdGltZXMgbGVzcyB0aGFuIDQgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2Uod2FpdF9sdF80aHJzID0gc3VtKHdhaXRfbHRfNGhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB3YWl0X2x0XzRocnMsIGdyb3VwID0geWVhciwgY29sID0gZmFjdG9yKHllYXIpKSkgKw0KICBnZW9tX2xpbmUoKQ0KDQojIHdhaXQgdGltZXMgbW9yZSB0aGFuIDQgaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2Uod2FpdF9ndF80aHJzID0gc3VtKHdhaXRfZ3RfNGhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB3YWl0X2d0XzRocnMsIGdyb3VwID0geWVhciwgY29sID0gZmFjdG9yKHllYXIpKSkgKw0KICBnZW9tX2xpbmUoKQ0KDQojIHdhaXQgdGltZXMgbW9yZSB0aGFuIDggaG91cnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2Uod2FpdF9ndF84aHJzID0gc3VtKHdhaXRfZ3RfOGhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB3YWl0X2d0XzhocnMsIGdyb3VwID0geWVhciwgY29sID0gZmFjdG9yKHllYXIpKSkgKw0KICBnZW9tX2xpbmUoKQ0KDQojIHdhaXQgdGltZXMgbW9yZSB0aGFuIDEyIGhvdXJzDQp3YWl0aW5nX3RpbWVzICU+JSANCiAgZ3JvdXBfYnkoeWVhciwgbW9udGgpICU+JSANCiAgc3VtbWFyaXNlKHdhaXRfZ3RfMTJocnMgPSBzdW0od2FpdF9ndF8xMmhycykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB3YWl0X2d0XzEyaHJzLCBncm91cCA9IHllYXIsIGNvbCA9IGZhY3Rvcih5ZWFyKSkpICsNCiAgZ2VvbV9saW5lKCkNCg0KYGBgDQoNCiMgSG93IGRvIHdhaXQgdGltZXMgdmFyeSBhY3Jvc3MgaGVhbHRoIGJvYXJkcz8NCg0KYGBge3J9DQojIGluIHRlcm1zIG9mIG51bWJlcnMNCndhaXRpbmdfdGltZXMgJT4lIA0KICBncm91cF9ieShkYXRlX3ltLCBoZWFsdGhfYm9hcmQpICU+JSANCiAgc3VtbWFyaXNlKHdhaXRfZ3RfOGhycyA9IHN1bSh3YWl0X2d0XzhocnMpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGRhdGVfeW0sIHkgPSB3YWl0X2d0XzhocnMsIGNvbCA9IGhlYWx0aF9ib2FyZCkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIk51bWJlciBvZiB3YWl0cyA+IDggaG91cnMgZm9yIGVhY2ggaGVhbHRoYm9hcmQiKQ0KDQojIGluIHRlcm1zIG9mIHByb3BvcnRpb24NCndhaXRpbmdfdGltZXNfcHJvcCAlPiUgDQogIGdyb3VwX2J5KGRhdGVfeW0sIGhlYWx0aF9ib2FyZCkgJT4lIA0KICBzdW1tYXJpc2UocHJvcF9ndF84aHJzID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UgKiBwcm9wX2d0XzhocnMpLw0KICAgICAgICAgICAgICBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZV95bSwgeSA9IHByb3BfZ3RfOGhycywgY29sID0gaGVhbHRoX2JvYXJkKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGxhYnModGl0bGUgPSAiUHJvcG9ydGlvbiBvZiB3YWl0cyA+IDggaG91cnMgZm9yIGVhY2ggaGVhbHRoYm9hcmQiKQ0KDQoNCiMgZmluZCB0b3AgNSBoZWFsdGhib2FyZHMgKGluIHRlcm1zIG9mIGF0dGVuZGFuY2VzKQ0KdG9wXzVfYXR0ZW5kYW5jZXNfYnlfaGIgPC0gd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZ3JvdXBfYnkoaGVhbHRoX2JvYXJkKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHQgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgc2xpY2VfbWF4KHRvdGFsX2F0dCwgbiA9IDUpDQoNCiMgZmluZCBib3R0b20gNSBoZWFsdGhib2FyZHMgKGluIHRlcm1zIG9mIGF0dGVuZGFuY2VzKQ0KYm90dG9tXzVfYXR0ZW5kYW5jZXNfYnlfaGIgPC0gd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZ3JvdXBfYnkoaGVhbHRoX2JvYXJkKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHQgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgc2xpY2VfbWluKHRvdGFsX2F0dCwgbiA9IDUpDQoNCiMgd2FpdCB0aW1lcyBhY3Jvc3MgdGhlIHRvcCA1IGhlYWx0aGJvYXJkcyA+IDggaG91cnMNCndhaXRpbmdfdGltZXNfcHJvcCAlPiUgDQogIGZpbHRlcihoZWFsdGhfYm9hcmQgJWluJSB0b3BfNV9hdHRlbmRhbmNlc19ieV9oYiRoZWFsdGhfYm9hcmQpICU+JSANCiAgZ3JvdXBfYnkoZGF0ZV95bSwgaGVhbHRoX2JvYXJkKSAlPiUgDQogIHN1bW1hcmlzZShwcm9wX2d0XzhocnMgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSAqIHByb3BfZ3RfOGhycykvDQogICAgICAgICAgICAgIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlX3ltLCB5ID0gcHJvcF9ndF84aHJzLCBjb2wgPSBoZWFsdGhfYm9hcmQpKSArDQogIGdlb21fbGluZSgpICsNCiAgbGFicyh0aXRsZSA9ICJQcm9wb3J0aW9uIG9mIHdhaXRzID4gOCBob3VycyBmb3IgdGhlIHRvcCA1IG1vc3QgYXR0ZW5kZWQgaGVhbHRoYm9hcmRzIikNCg0KIyB3YWl0IHRpbWVzIGFjcm9zcyB0aGUgYm90dG9tIDUgaGVhbHRoYm9hcmRzID4gOCBob3Vycw0Kd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZmlsdGVyKGhlYWx0aF9ib2FyZCAlaW4lIGJvdHRvbV81X2F0dGVuZGFuY2VzX2J5X2hiJGhlYWx0aF9ib2FyZCkgJT4lIA0KICBncm91cF9ieShkYXRlX3ltLCBoZWFsdGhfYm9hcmQpICU+JSANCiAgc3VtbWFyaXNlKHByb3BfZ3RfOGhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF84aHJzKS8NCiAgICAgICAgICAgICAgc3VtKHRvdGFsX2F0dGVuZGFuY2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGRhdGVfeW0sIHkgPSBwcm9wX2d0XzhocnMsIGNvbCA9IGhlYWx0aF9ib2FyZCkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIlByb3BvcnRpb24gb2Ygd2FpdHMgPiA4IGhvdXJzIGZvciB0aGUgYm90dG9tIDUgbW9zdCBhdHRlbmRlZCBoZWFsdGhib2FyZHMiKQ0KDQoNCiMgd2FpdCB0aW1lcyBhY3Jvc3MgdGhlIHRvcCA1IGhlYWx0aGJvYXJkcyA+IDEyIGhvdXJzDQp3YWl0aW5nX3RpbWVzX3Byb3AgJT4lIA0KICBmaWx0ZXIoaGVhbHRoX2JvYXJkICVpbiUgdG9wXzVfYXR0ZW5kYW5jZXNfYnlfaGIkaGVhbHRoX2JvYXJkKSAlPiUgDQogIGdyb3VwX2J5KGRhdGVfeW0sIGhlYWx0aF9ib2FyZCkgJT4lIA0KICBzdW1tYXJpc2UocHJvcF9ndF8xMmhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF8xMmhycykvDQogICAgICAgICAgICAgIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlX3ltLCB5ID0gcHJvcF9ndF8xMmhycywgY29sID0gaGVhbHRoX2JvYXJkKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGxhYnModGl0bGUgPSAiUHJvcG9ydGlvbiBvZiB3YWl0cyA+IDEyIGhvdXJzIGZvciB0aGUgYm90dG9tIDUgbW9zdCBhdHRlbmRlZCBoZWFsdGhib2FyZHMiKQ0KDQojIHdhaXQgdGltZXMgYWNyb3NzIHRoZSBib3R0b20gNSBoZWFsdGhib2FyZHMgPiAxMiBob3Vycw0Kd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZmlsdGVyKGhlYWx0aF9ib2FyZCAlaW4lIGJvdHRvbV81X2F0dGVuZGFuY2VzX2J5X2hiJGhlYWx0aF9ib2FyZCkgJT4lIA0KICBncm91cF9ieShkYXRlX3ltLCBoZWFsdGhfYm9hcmQpICU+JSANCiAgc3VtbWFyaXNlKHByb3BfZ3RfMTJocnMgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSAqIHByb3BfZ3RfMTJocnMpLw0KICAgICAgICAgICAgICBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZV95bSwgeSA9IHByb3BfZ3RfMTJocnMsIGNvbCA9IGhlYWx0aF9ib2FyZCkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIlByb3BvcnRpb24gb2Ygd2FpdHMgPiAxMiBob3VycyBmb3IgdGhlIGJvdHRvbSA1IG1vc3QgYXR0ZW5kZWQgaGVhbHRoYm9hcmRzIikNCg0KYGBgDQoNCmBgYHtyfQ0KDQojIHdhaXQgdGltZXMgYWNyb3NzIGVhY2ggaG9zcGl0YWwgaW4gdGhlIEJvcmRlcnMgaGVhbHRoYm9hcmQNCndhaXRpbmdfdGltZXNfcHJvcCAlPiUgDQogICMgZmlsdGVyKGhlYWx0aF9ib2FyZCA9PSAiTkhTIEJvcmRlcnMiKSAlPiUgDQogIGdyb3VwX2J5KGRhdGVfeW0sIGhvc3BpdGFsX25hbWUpICU+JSANCiAgc3VtbWFyaXNlKHByb3BfZ3RfOGhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF84aHJzKS8NCiAgICAgICAgICAgICAgc3VtKHRvdGFsX2F0dGVuZGFuY2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGRhdGVfeW0sIHkgPSBwcm9wX2d0XzhocnMsIGNvbCA9IGhvc3BpdGFsX25hbWUpKSArDQogIGdlb21fbGluZSgpICsNCiAgbGFicyh0aXRsZSA9ICJQcm9wb3J0aW9uIG9mIHdhaXRzID4gOCBob3VycyBmb3IgdGhlIGJvdHRvbSA1IG1vc3QgYXR0ZW5kZWQgaGVhbHRoYm9hcmRzIikgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCmBgYA0KDQojIG1vc3QgYWZmZWN0ZWQgaGVhbHRoYm9hcmRzDQpgYGB7cn0NCiMgaW4gdGVybXMgb2YgcHJvcG9ydGlvbg0KdG9wXzVfaG9zcGl0YWxfcHJvcHMgPC0gd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZ3JvdXBfYnkoaG9zcGl0YWxfbmFtZSkgJT4lIA0KICBzdW1tYXJpc2UobWF4X3Byb3AgPSBtYXgocHJvcF9ndF8xMmhycykpICU+JSANCiAgYXJyYW5nZShkZXNjKG1heF9wcm9wKSkgJT4lIA0KICBzbGljZV9tYXgobWF4X3Byb3AsIG4gPSA1KQ0KICANCiMgaW4gdGVybXMgb2YgbnVtYmVycw0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGdyb3VwX2J5KGhvc3BpdGFsX25hbWUpICU+JSANCiAgc3VtbWFyaXNlKG1heF9wcm9wID0gbWF4KHdhaXRfZ3RfMTJocnMpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhtYXhfcHJvcCkpDQoNCmBgYA0KDQpgYGB7cn0NCg0KIyB3YWl0IHRpbWVzIGFjcm9zcyBlYWNoIGhvc3BpdGFsIGluIHRoZSBCb3JkZXJzIGhlYWx0aGJvYXJkDQp3YWl0aW5nX3RpbWVzX3Byb3AgJT4lIA0KICBmaWx0ZXIoaG9zcGl0YWxfbmFtZSAlaW4lIHRvcF81X2hvc3BpdGFsX3Byb3BzJGhvc3BpdGFsX25hbWUpICU+JSANCiAgZ3JvdXBfYnkoZGF0ZV95bSwgaG9zcGl0YWxfbmFtZSkgJT4lIA0KICBzdW1tYXJpc2UocHJvcF9ndF8xMmhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF8xMmhycykvDQogICAgICAgICAgICAgIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlX3ltLCB5ID0gcHJvcF9ndF8xMmhycywgY29sID0gaG9zcGl0YWxfbmFtZSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIlByb3BvcnRpb24gb2Ygd2FpdHMgPiA4IGhvdXJzIGZvciB0aGUgYm90dG9tIDUgbW9zdCBhdHRlbmRlZCBoZWFsdGhib2FyZHMiKQ0KDQpgYGANCiMjIEZvciB0aGUgeWVhcnMgMjAwNyB0byAyMDE5LCBwcm92aWRlIGEgc3VtbWFyeSBvZiB0aGUgZWZmZWN0cyBvZiB3YWl0IHRpbWVzIGF0IGRpZmZlcmVudCB0aW1lcyBvZiB0aGUgeWVhci4NCmBgYHtyfQ0KDQp3YWl0aW5nX3RpbWVzX3N1bW1hcnkgPC0gd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgZmlsdGVyKHllYXIgPD0gMjAxOSkgJT4lIA0KICBtdXRhdGUobW9udGggPSBmYWN0b3IobW9udGgsIGxldmVscyA9IGMoIkp1bHkiLCAiQXVndXN0IiwgIlNlcHRlbWJlciIsICJPY3RvYmVyIiwgIk5vdmVtYmVyIiwgIkRlY2VtYmVyIiwgIkphbnVhcnkiLCAiRmVicnVhcnkiLCAiTWFyY2giLCAiQXByaWwiLCAiTWF5IiwgIkp1bmUiKSkpICU+JSANCiAgZ3JvdXBfYnkobW9udGgpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZHMgPSBtZWFuKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgcHJvcF9sdF80aHJzID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UgKiBwcm9wX2x0XzRocnMpLyBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICBwcm9wX2d0XzRocnMgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSAqIHByb3BfZ3RfNGhycykvIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHByb3BfZ3RfOGhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF84aHJzKS8gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgcHJvcF9ndF8xMmhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9ndF8xMmhycykvIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSkgDQoNCndhaXRpbmdfdGltZXNfc3VtbWFyeSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdG90YWxfYXR0ZW5kcykpICsNCiAgZ2VvbV9jb2woKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBsYWJzKHkgPSAiQXZlcmFnZSBtb250aGx5IGF0dGVuZGFuY2VzIiwNCiAgICAgICB0aXRsZSA9ICJBdmVyYWdlIEEmRSBhdHRlbmRhbmNlcyIsDQogICAgICAgc3VidGl0bGUgPSAiRnJvbSBKdWx5IDIwMDcgdG8gRGVjZW1iZXIgMjAxOSAiKSArDQogIGdlb21fc21vb3RoKCkNCg0Kd2FpdGluZ190aW1lc19zdW1tYXJ5ICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSBwcm9wX2x0XzRocnMsIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgbGFicyh0aXRsZSA9ICJTZWFzb25hbGl0eSBvZiBwcm9wb3J0aW9uIG9mIHZpc2l0cyB3aXRoIGEgd2FpdCB0aW1lIDwgNCBob3VycyIsDQogICAgICAgICBzdWJ0aXRsZSA9ICIyMDA3IHRvIDIwMTkiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsNCiAgZ2VvbV9zbW9vdGgoKQ0KDQp3YWl0aW5nX3RpbWVzX3N1bW1hcnkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtb250aCwgeSA9IHByb3BfZ3RfNGhycywgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICAgIGxhYnModGl0bGUgPSAiU2Vhc29uYWxpdHkgb2YgcHJvcG9ydGlvbiBvZiB2aXNpdHMgd2l0aCBhIHdhaXQgdGltZSA+IDQgaG91cnMiLA0KICAgICAgICAgc3VidGl0bGUgPSAiMjAwNyB0byAyMDE5IikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArDQogIGdlb21fc21vb3RoKCkNCg0KDQp3YWl0aW5nX3RpbWVzX3N1bW1hcnkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gcHJvcF9ndF84aHJzLCBncm91cCA9IDEpKSArDQogIGdlb21fcG9pbnQoKSArDQogICAgbGFicyh0aXRsZSA9ICJTZWFzb25hbGl0eSBvZiBwcm9wb3J0aW9uIG9mIHZpc2l0cyB3aXRoIGEgd2FpdCB0aW1lID4gOCBob3VycyIsDQogICAgICAgICBzdWJ0aXRsZSA9ICIyMDA3IHRvIDIwMTkiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsNCiAgZ2VvbV9zbW9vdGgoKQ0KDQoNCndhaXRpbmdfdGltZXNfc3VtbWFyeSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gcHJvcF9ndF8xMmhycywgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgICBsYWJzKHRpdGxlID0gIlNlYXNvbmFsaXR5IG9mIHByb3BvcnRpb24gb2YgdmlzaXRzIHdpdGggYSB3YWl0IHRpbWUgPiAxMiBob3VycyIsDQogICAgICAgICBzdWJ0aXRsZSA9ICJQcmUtY292aWQ6IDIwMDcgdG8gMjAxOSIsDQogICAgICAgICB5ID0gIlBlcmNlbnRhZ2Ugb2YgYXR0ZW5kYW5jZXMgPiAxMiBob3VycyIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIGdlb21fc21vb3RoKHNlID0gRkFMU0UpDQoNCg0KDQoNCmBgYA0KVGhlIG51bWJlciBvZiBBJkUgYXR0ZW5kYW5jZXMgZGVjcmVhc2UgZHVyaW5nIHRoZSB3aW50ZXIgbW9udGhzIGhvd2V2ZXIgdGhlIHByb3BvcnRpb24gb2Ygd2FpdCB0aW1lcyBncmVhdGVyIHRoYW4gNGhvdXJzIGluY3JlYXNlcyBzaWduaWZpY2FudGx5IGJldHdlZW4gTm92ZW1iZXIgYW5kIEZlYnJ1YXJ5IGhpZ2hsaWdodGluZyB0aGF0IHRoZSBjb21wbGV4aXR5IG9mIGNhc2VzIGluIHRoZSB3aW50ZXIgbWVhbiB0aGF0IGl0IHRha2VzIGhvc3BpdGFscyBsb25nZXIgdG8gZGlzY2hhcmdlIHBhdGllbnRzLiBQZXJoYXBzIGNvbWJpbmluZyB0aGlzIG91dHB1dCB3aXRoIHRoZSBiZWQgb2NjdXBhdGlvbiByYXRlcyBkdXJpbmcgdGhlIHdpbnRlciBtb250aHMgY291bGQgZnVydGhlciBzdXBwbGVtZW50IHRoaXMgcmVsYXRpb25zaGlwLiANCg0KDQpgYGB7cn0NCg0Kd2FpdGluZ190aW1lc19wcm9wICU+JSANCiAgIyBmaWx0ZXIoeWVhciA8PSAyMDE5KSAlPiUgDQogIG11dGF0ZShtb250aCA9IGZhY3Rvcihtb250aCwgbGV2ZWxzID0gYygiSnVseSIsICJBdWd1c3QiLCAiU2VwdGVtYmVyIiwgIk9jdG9iZXIiLCAiTm92ZW1iZXIiLCAiRGVjZW1iZXIiLCAiSmFudWFyeSIsICJGZWJydWFyeSIsICJNYXJjaCIsICJBcHJpbCIsICJNYXkiLCAiSnVuZSIpKSkgJT4lIA0KICBncm91cF9ieShtb250aCwgaGVhbHRoX2JvYXJkKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRzID0gbWVhbih0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHByb3BfbHRfNGhycyA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlICogcHJvcF9sdF80aHJzKS8gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgcHJvcF9ndF80aHJzID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UgKiBwcm9wX2d0XzRocnMpLyBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICBwcm9wX2d0XzhocnMgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSAqIHByb3BfZ3RfOGhycykvIHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHByb3BfZ3RfMTJocnMgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSAqIHByb3BfZ3RfMTJocnMpLyBzdW0odG90YWxfYXR0ZW5kYW5jZSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSBwcm9wX2d0XzEyaHJzLCBncm91cCA9IGhlYWx0aF9ib2FyZCwgY29sb3VyID0gaGVhbHRoX2JvYXJkKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGxhYnModGl0bGUgPSAiU2Vhc29uYWxpdHkgb2YgcHJvcG9ydGlvbiBvZiB2aXNpdHMgd2l0aCBhIHdhaXQgdGltZSA+IDEyIGhvdXJzIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQoNCg0KIyBIb3cgZG8gYXR0ZW5kYW5jZXMgdG8gZGlmZmVyZW50IHNwZWNpYWx0aWVzIGNoYW5nZSBvdmVyIHRpbWU/DQoNCmBgYHtyfQ0KDQpzcGVjaWFsdGllc19yYXcgPC0gcmVhZF9jc3YoaGVyZSgicmF3X2RhdGEvbm9uX2NvdmlkL2lucGF0aWVudF9hbmRfZGF5Y2FzZV9ieV9uaHNfYm9hcmRfb2ZfdHJlYXRtZW50X2FuZF9zcGVjaWFsdHkuY3N2IikpICU+JQ0KICBjbGVhbl9uYW1lcygpDQoNCnNwZWNpYWx0aWVzX3Jhdw0KDQpgYGANCg0KYGBge3J9DQoNCnNwZWNpYWx0aWVzIDwtIHNwZWNpYWx0aWVzX3JhdyAlPiUgDQogIGlubmVyX2pvaW4oaGIsICJoYiIpICU+JSANCiAgaW5uZXJfam9pbihob3NwaXRhbHMsICJsb2NhdGlvbiIpICU+JSANCiAgc2VsZWN0KC1lbmRzX3dpdGgoInFmIiksIC1oYiwgLSBzcGVjaWFsdHkpICU+JSANCiAgc2VsZWN0KHF1YXJ0ZXIsIGhiX25hbWUsIGxvY2F0aW9uLCBsb2NhdGlvbl9uYW1lLCBldmVyeXRoaW5nKCkpICU+JSANCiAgbXV0YXRlKHllYXIgPSBhcy5udW1lcmljKHN0cl9zdWIocXVhcnRlciwxLCA0KSksIC5iZWZvcmUgPSBxdWFydGVyKSAlPiUgDQogIG11dGF0ZShpc19jb3ZpZF95ZWFyID0gY2FzZV93aGVuKA0KICAgIHllYXIgPj0gMjAyMCB+IFRSVUUsDQogICAgeWVhciA8IDIwMjAgfiBGQUxTRQ0KICApKQ0KICAjIG11dGF0ZShxdWFydGVyID0gc3RyX3N1YihxdWFydGVyLCAtMiwgLTEpKQ0KDQpzcGVjaWFsdGllcw0KDQpgYGANCg0KIyBhbGwgZXBpc29kZXMgdnMgdGltZQ0KYGBge3J9DQoNCnNwZWNpYWx0aWVzICU+JSANCiAgZGlzdGluY3QoYWRtaXNzaW9uX3R5cGUpDQoNCnNwZWNpYWx0aWVzICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlcikgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCBJbnBhdGllbnRzIGFuZCBEYXkgY2FzZXMiKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9lcGlzb2RlcyA9IHN1bShlcGlzb2RlcykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHRvdGFsX2VwaXNvZGVzLCBncm91cCA9IDEpKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6Y29tbWEsIGV4cGFuZCA9IGMoMCwwKSwgbGltaXRzID0gYygwLE5BKSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArDQogIGxhYnModGl0bGUgPSAiVG90YWwgYWRtaXNzaW9ucyBmb3IgQWxsIElucGF0aWVudHMgYW5kIERheSBDYXNlcyIsDQogICAgICAgeCA9ICJRdWFydGVyIiwNCiAgICAgICB5ID0gIlRvdGFsIEVwaXNvZGVzIikNCg0KYGBgDQoNCiMgQWxsIERheSBDYXNlcw0KDQpgYGB7cn0NCg0Kc3BlY2lhbHRpZXMgJT4lIA0KICBkaXN0aW5jdChhZG1pc3Npb25fdHlwZSkNCg0Kc3BlY2lhbHRpZXMgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBhZG1pc3Npb25fdHlwZSkgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgJWluJSBjKCJBbGwgRGF5IGNhc2VzIiwgIkFsbCBJbnBhdGllbnRzIikpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2VwaXNvZGVzID0gc3VtKGVwaXNvZGVzKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBxdWFydGVyLCB5ID0gdG90YWxfZXBpc29kZXMsIGNvbG91ciA9IGFkbWlzc2lvbl90eXBlKSkgKw0KICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gYWRtaXNzaW9uX3R5cGUpKSArDQogIGdlb21fcG9pbnQoKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmNvbW1hLCBleHBhbmQgPSBjKDAsMCksIGxpbWl0cyA9IGMoMCxOQSkpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKw0KICBsYWJzKHRpdGxlID0gIlRvdGFsIGFkbWlzc2lvbnMgZm9yIEFsbCBEYXkgQ2FzZXMgYW5kIEFsbCBJbnBhdGllbnRzIiwNCiAgICAgICB4ID0gIlF1YXJ0ZXIiLA0KICAgICAgIHkgPSAiVG90YWwgRXBpc29kZXMiLA0KICAgICAgIGNvbCA9ICJBZG1pc3Npb24gVHlwZSIpDQoNCg0KYGBgDQoNCmBgYHtyfQ0KDQphbGxfaW5wYXRpZW50X2NhdHMgPC0gYygiRWxlY3RpdmUgSW5wYXRpZW50cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICJFbWVyZ2VuY3kgSW5wYXRpZW50cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICJUcmFuc2ZlcnMiKQ0KDQpzcGVjaWFsdGllcyAlPiUgDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIGFkbWlzc2lvbl90eXBlKSAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSAlaW4lIGFsbF9pbnBhdGllbnRfY2F0cykgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfZXBpc29kZXMgPSBzdW0oZXBpc29kZXMpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHF1YXJ0ZXIsIHkgPSB0b3RhbF9lcGlzb2RlcywgY29sb3VyID0gYWRtaXNzaW9uX3R5cGUpKSArDQogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBhZG1pc3Npb25fdHlwZSkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6Y29tbWEsIGV4cGFuZCA9IGMoMCwwKSwgbGltaXRzID0gYygwLE5BKSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArDQogIGxhYnModGl0bGUgPSAiVG90YWwgYWRtaXNzaW9ucyBmb3IgSW5wYXRpZW50cyIsDQogICAgICAgeCA9ICJRdWFydGVyIiwNCiAgICAgICB5ID0gIlRvdGFsIEVwaXNvZGVzIiwNCiAgICAgICBjb2wgPSAiQWRtaXNzaW9uIFR5cGUiKQ0KDQpgYGANCg0KYGBge3J9DQoNCnNwZWNpYWx0aWVzICU+JSANCiAgZGlzdGluY3QoYWRtaXNzaW9uX3R5cGUsIHNwZWNpYWx0eV9uYW1lKQ0KDQpgYGANCg0KYGBge3J9DQoNCnNwZWNpYWx0aWVzICU+JSANCiAgZ3JvdXBfYnkocXVhcnRlciwgYWRtaXNzaW9uX3R5cGUsIHNwZWNpYWx0eV9uYW1lKSAlPiUgDQogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiRW1lcmdlbmN5IElucGF0aWVudHMiKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9lcGlzb2RlcyA9IHN1bShlcGlzb2RlcykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IHRvdGFsX2VwaXNvZGVzLCBjb2xvdXIgPSBzcGVjaWFsdHlfbmFtZSkpICsNCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNwZWNpYWx0eV9uYW1lKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpjb21tYSwgZXhwYW5kID0gYygwLDApLCBsaW1pdHMgPSBjKDAsMTAwMDApKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsNCiAgbGFicyh0aXRsZSA9ICJUb3RhbCBhZG1pc3Npb25zIGZvciBFbWVyZ2VuY3kgSW5wYXRpZW50cyIsDQogICAgICAgc3VidGl0bGUgPSAiU3BsaXQgYnkgc3BlY2lhbHR5IiwNCiAgICAgICB4ID0gIlF1YXJ0ZXIiLA0KICAgICAgIHkgPSAiVG90YWwgRXBpc29kZXMiLA0KICAgICAgIGNvbCA9ICJBZG1pc3Npb24gVHlwZSIpDQoNCmBgYA0KDQojIFdoaWNoIGRlcGFydG1lbnRzIGNoYW5nZWQgdGhlIG1vc3QgYmV0d2VlbiBDb3ZpZCBhbmQgcHJlLWNvdmlkDQpgYGB7cn0NCg0KdG90YWxfYWRtaXNzaW9ucyA8LSBzcGVjaWFsdGllcyAlPiUgDQogIGdyb3VwX2J5KGlzX2NvdmlkX3llYXIpICU+JSANCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwgSW5wYXRpZW50cyBhbmQgRGF5IGNhc2VzIikgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYWRtaXNzaW9ucyA9IHN1bShlcGlzb2RlcykpICU+JSANCiAgcHVsbCh0b3RhbF9hZG1pc3Npb25zKQ0KDQpjaGFuZ2VfaW5fYXRfc3BlY2lhbHRpZXMgPC0gc3BlY2lhbHRpZXMgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgJWluJSBjKGFsbF9pbnBhdGllbnRfY2F0cywgIkFsbCBEYXkgY2FzZXMiKSkgJT4lIA0KICBncm91cF9ieShhZG1pc3Npb25fdHlwZSwgc3BlY2lhbHR5X25hbWUsIGlzX2NvdmlkX3llYXIpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2VwaXNvZGVzID0gc3VtKGVwaXNvZGVzKSkgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gaXNfY292aWRfeWVhciwgdmFsdWVzX2Zyb20gPSB0b3RhbF9lcGlzb2RlcykgJT4lIA0KICByZW5hbWUoImNvdmlkX3llYXIiID0gIlRSVUUiLCAicHJlX2NvdmlkX3llYXIiID0gIkZBTFNFIikgJT4lIA0KICBtdXRhdGUocHJlX2NvdmlkX3llYXJfcHJvcCA9IHByZV9jb3ZpZF95ZWFyIC8gdG90YWxfYWRtaXNzaW9uc1sxXSwNCiAgICAgICAgIGNvdmlkX3llYXJfcHJvcCA9IGNvdmlkX3llYXIgLyB0b3RhbF9hZG1pc3Npb25zWzJdLA0KICAgICAgICAgcGVyY2VudGFnZV9jaGFuZ2UgPSAoKGNvdmlkX3llYXJfcHJvcCAvIHByZV9jb3ZpZF95ZWFyX3Byb3ApIC0gMSkgKiAxMDApICU+JSANCiAgdW5ncm91cCgpDQoNCg0KYGBgDQoNCg0KDQpgYGB7cn0NCg0Kc3BlY2lhbHRpZXMgJT4lIA0KICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCBEYXkgY2FzZXMiICYgc3BlY2lhbHR5X25hbWUgPT0gIkNhcmRpb3Rob3JhY2ljIFN1cmdlcnkiKSAlPiUgDQogIGdyb3VwX2J5KGlzX2NvdmlkX3llYXIpICU+JSANCiAgc3VtbWFyaXNlKGNvdW50ID0gc3VtKGVwaXNvZGVzKSkNCg0KYGBgDQoNCmBgYHtyfQ0KIyB0b3AgNSBjaGFuZ2VzIGluIHNwZWNpYWx0eSBwcm9wb3J0aW9uDQpjaGFuZ2VfaW5fYXRfc3BlY2lhbHRpZXMgJT4lIA0KICBzbGljZV9tYXgocGVyY2VudGFnZV9jaGFuZ2UsIG4gPSA1KQ0KDQojIHNvcnQgYnkgbGFyZ2VzdCBwcm9wb3J0aW9uLCB0b3AgNQ0KY2hhbmdlX2luX2F0X3NwZWNpYWx0aWVzICU+JSANCiAgc2xpY2VfbWF4KHBlcmNlbnRhZ2VfY2hhbmdlLCBuID0gNSkgJT4lIA0KICBhcnJhbmdlKGRlc2MoY292aWRfeWVhcl9wcm9wKSkNCg0KYGBgDQoNCmBgYHtyfQ0KDQpjaGFuZ2VfaW5fYXRfc3BlY2lhbHRpZXMgJT4lIA0KICBmaWx0ZXIoY292aWRfeWVhciA+IDEwMDApICU+JSANCiAgc2xpY2VfbWF4KHBlcmNlbnRhZ2VfY2hhbmdlLCBuID0gNSkgJT4lIA0KICBtdXRhdGUobGFiZWwgPSBzdHJfYyhzcGVjaWFsdHlfbmFtZSwgIlxuKCIsIGFkbWlzc2lvbl90eXBlLCAiKSIpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHJlb3JkZXIobGFiZWwsIHNvcnQocGVyY2VudGFnZV9jaGFuZ2UpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gcGVyY2VudGFnZV9jaGFuZ2UpKSArDQogIGdlb21fY29sKCkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLDApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKSArDQogIGxhYnMoeSA9ICJQZXJjZW50YWdlIEluY3JlYXNlICglKSIsDQogICAgICAgdGl0bGUgPSAiVG9wIDUgaW5jcmVhc2VzIGluIGhvc3BpdGFsIGFkbWlzc2lvbnMgKGJ5IHNwZWNpYWx0eSBhbmQgYWRtaXNzaW9uIHR5cGUpIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJNb3JlIHRoYW4gMSwwMDAgYWRtaXNzaW9ucyIpDQoNCmBgYA0KDQpgYGB7cn0NCg0KY2hhbmdlX2luX3NwZWNpYWx0aWVzIDwtIHNwZWNpYWx0aWVzICU+JSANCiAgZ3JvdXBfYnkoc3BlY2lhbHR5X25hbWUsIGlzX2NvdmlkX3llYXIpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2VwaXNvZGVzID0gc3VtKGVwaXNvZGVzKSkgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gaXNfY292aWRfeWVhciwgdmFsdWVzX2Zyb20gPSB0b3RhbF9lcGlzb2RlcykgJT4lIA0KICByZW5hbWUoImNvdmlkX3llYXIiID0gIlRSVUUiLCAicHJlX2NvdmlkX3llYXIiID0gIkZBTFNFIikgJT4lIA0KICBtdXRhdGUocHJlX2NvdmlkX3llYXJfcHJvcCA9IHByZV9jb3ZpZF95ZWFyIC8gdG90YWxfYWRtaXNzaW9uc1sxXSwNCiAgICAgICAgIGNvdmlkX3llYXJfcHJvcCA9IGNvdmlkX3llYXIgLyB0b3RhbF9hZG1pc3Npb25zWzJdLA0KICAgICAgICAgcGVyY2VudGFnZV9jaGFuZ2UgPSAoKGNvdmlkX3llYXJfcHJvcCAvIHByZV9jb3ZpZF95ZWFyX3Byb3ApIC0gMSkgKiAxMDApICU+JSANCiAgdW5ncm91cCgpDQoNCmNoYW5nZV9pbl9zcGVjaWFsdGllcyAlPiUgDQogIHNsaWNlX21heChwZXJjZW50YWdlX2NoYW5nZSwgbiA9IDUpICU+JSANCiAgZmlsdGVyKHBlcmNlbnRhZ2VfY2hhbmdlID4gMCkgJT4lIA0KICBhcnJhbmdlKGRlc2MocGVyY2VudGFnZV9jaGFuZ2UpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHJlb3JkZXIoc3BlY2lhbHR5X25hbWUsIHBlcmNlbnRhZ2VfY2hhbmdlLCBkZWNyZWFzaW5nID0gVFJVRSksDQogICAgICAgICAgICAgeSA9IHBlcmNlbnRhZ2VfY2hhbmdlKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwwKSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgKw0KICBsYWJzKHkgPSAiUGVyY2VudGFnZSBJbmNyZWFzZSAoJSkiLA0KICAgICAgIHRpdGxlID0gIlRvcCA1IGNoYW5nZXMgaW4gaG9zcGl0YWwgYWRtaXNzaW9ucyAoYnkgc3BlY2lhbHR5KSAtIHByZS1Db3ZpZCB2cyBDb3ZpZCIsDQogICAgICAgc3VidGl0bGUgPSAiTW9yZSB0aGFuIDEsMDAwIGFkbWlzc2lvbnMiKQ0KDQpgYGANCg0KYGBge3J9DQoNCg0Kd3Rfd2l0aF9kaXNjaGFyZ2VzIDwtIHdhaXRpbmdfdGltZXNfcmF3ICU+JSANCiAgbXV0YXRlKGRhdGVfeW0gPSB5bShtb250aCksIC5iZWZvcmUgPSBtb250aCwNCiAgICAgICAgIG1vbnRoID0gbW9udGgoZGF0ZV95bSwgbGFiZWwgPSBUUlVFLCBhYmJyID0gRkFMU0UpLA0KICAgICAgICAgeWVhciA9IHllYXIoZGF0ZV95bSkpICU+JSANCiAgbGVmdF9qb2luKGhiLCBjKCJoYnQiID0gImhiIikpICU+JSANCiAgbGVmdF9qb2luKGhvc3BpdGFscywgYygidHJlYXRtZW50X2xvY2F0aW9uIiA9ICJsb2NhdGlvbiIpKSAlPiUgDQogIHJlbmFtZSh0b3RhbF9hdHRlbmRhbmNlID0gbnVtYmVyX29mX2F0dGVuZGFuY2VzX2FnZ3JlZ2F0ZSwNCiAgICAgICAgIHdhaXRfbHRfNGhycyA9IG51bWJlcl9tZWV0aW5nX3RhcmdldF9hZ2dyZWdhdGUsDQogICAgICAgICB3YWl0X2d0XzhocnMgPSBhdHRlbmRhbmNlX2dyZWF0ZXI4aHJzLA0KICAgICAgICAgd2FpdF9ndF8xMmhycyA9IGF0dGVuZGFuY2VfZ3JlYXRlcjEyaHJzLA0KICAgICAgICAgaGVhbHRoX2JvYXJkID0gaGJfbmFtZSwNCiAgICAgICAgIGhvc3BpdGFsX2lkID0gdHJlYXRtZW50X2xvY2F0aW9uLCANCiAgICAgICAgIGhvc3BpdGFsX25hbWUgPSBsb2NhdGlvbl9uYW1lKSAlPiUgDQogIHNlbGVjdCgtZW5kc193aXRoKCJxZiIpKSAlPiUgDQogIHNlbGVjdChkYXRlX3ltLCB5ZWFyLCBtb250aCwgaGVhbHRoX2JvYXJkLCBob3NwaXRhbF9pZCwgaG9zcGl0YWxfbmFtZSwNCiAgICAgICAgIGV2ZXJ5dGhpbmcoKSwgLWNvdW50cnksIC0gaGJ0KQ0KDQojIGNoZWNrIGlmIHRoZXJlIGlzIGEgdHJlbmQgYWNyb3NzIGFsbCB5ZWFycw0Kd3Rfd2l0aF9kaXNjaGFyZ2VzICU+JSANCiAgZ3JvdXBfYnkoZGF0ZV95bSwgaG9zcGl0YWxfbmFtZSkgJT4lIA0KICBzdW1tYXJpc2UodHJhbnNmZXJzID0gc3VtKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl90cmFuc2ZlciwgbmEucm0gPSBUUlVFKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlX3ltLCB5ID0gdHJhbnNmZXJzLCBjb2wgPSBob3NwaXRhbF9uYW1lKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KIyBjaGVjayBpZiB0aGVyZSBpcyBhIHNlYXNvbmFsIHRyZW5kDQp3dF93aXRoX2Rpc2NoYXJnZXMgJT4lIA0KICBtdXRhdGUobW9udGggPSBmYWN0b3IobW9udGgsIGxldmVscyA9IGMoIkp1bHkiLCAiQXVndXN0IiwgIlNlcHRlbWJlciIsICJPY3RvYmVyIiwgIk5vdmVtYmVyIiwgIkRlY2VtYmVyIiwgIkphbnVhcnkiLCAiRmVicnVhcnkiLCAiTWFyY2giLCAiQXByaWwiLCAiTWF5IiwgIkp1bmUiKSkpICU+JSANCiAgZ3JvdXBfYnkobW9udGgsIGhlYWx0aF9ib2FyZCkgJT4lIA0KICBzdW1tYXJpc2UodHJhbnNmZXJzID0gc3VtKGRpc2NoYXJnZV9kZXN0aW5hdGlvbl9vdGhlcl9zcGVjaWFsdHksIG5hLnJtID0gVFJVRSkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB0cmFuc2ZlcnMsIGdyb3VwID0gaGVhbHRoX2JvYXJkLCBjb2wgPSBoZWFsdGhfYm9hcmQpKSArDQogIGdlb21fbGluZSgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGZhY2V0X3dyYXAofiBoZWFsdGhfYm9hcmQsIHNjYWxlcyA9ICJmcmVlX3kiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpDQoNCmBgYA0KDQojIEJlZCBvY2N1cGFuY3kgZGF0YQ0KDQpgYGB7cn0NCg0KYmVkc19yYXcgPC0gcmVhZF9jc3YoaGVyZSgicmF3X2RhdGEvbm9uX2NvdmlkL2JlZHNfYnlfbmhzX2JvYXJkX29mX3RyZWF0bWVudF9hbmRfc3BlY2lhbHR5LmNzdiIpKSAlPiUgDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICBzZWxlY3QoLWVuZHNfd2l0aCgicWYiKSkgDQoNCmBgYA0KDQpgYGB7cn0NCiMgYWxsIHNwZWNpYWx0eSBuYW1lcw0KYmVkc19yYXcgJT4lIA0KICBncm91cF9ieShzcGVjaWFsdHlfbmFtZSkgJT4lIA0KICBzdW1tYXJpc2Uoc3VtKGFsbF9zdGFmZmVkX2JlZGRheXMpKQ0KDQpiZWRzX3JhdyAlPiUgDQogIGZpbHRlcihzcGVjaWFsdHlfbmFtZSAhPSAiQWxsIEFjdXRlIiAmIHNwZWNpYWx0eV9uYW1lICE9ICJBbGwgU3BlY2lhbHRpZXMiKSAlPiUgDQogICMgZ3JvdXBfYnkoc3BlY2lhbHR5X25hbWUpICU+JSANCiAgc3VtbWFyaXNlKHN1bShhbGxfc3RhZmZlZF9iZWRkYXlzKSkNCiMgMjA5MTM5NjYwDQoNCg0KYmVkcyA8LSBiZWRzX3JhdyAlPiUgDQogIGxlZnRfam9pbihoYiwgImhiIikgJT4lIA0KICBsZWZ0X2pvaW4oaG9zcGl0YWxzLCAibG9jYXRpb24iKSAlPiUgDQogIHNlbGVjdChxdWFydGVyLCBoYiwgaGJfbmFtZSwgbG9jYXRpb24sIGxvY2F0aW9uX25hbWUsIHNwZWNpYWx0eV9uYW1lOnBlcmNlbnRhZ2Vfb2NjdXBhbmN5KSAlPiUgDQogIG11dGF0ZSgpDQoNCg0KDQpgYGANCg0KYGBge3J9DQoNCmJlZHMgJT4lIA0KICBncm91cF9ieShxdWFydGVyKSAlPiUgDQogIHN1bW1hcmlzZShzdGFmZmVkX2JlZHMgPSBzdW0oYWxsX3N0YWZmZWRfYmVkZGF5cyksDQogICAgICAgICAgICBvY2N1cGllZF9iZWRzID0gc3VtKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpLCANCiAgICAgICAgICAgIG9jY3VwYXRpb25fcGVyY2VudGFnZSA9IG9jY3VwaWVkX2JlZHMgLyBzdGFmZmVkX2JlZHMgKiAxMDApICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IG9jY3VwYXRpb25fcGVyY2VudGFnZSwgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX2xpbmUoKQ0KDQpgYGANCg0KIyBXYWl0IHRpbWVzIC0gYmFzZWxpbmUgKHByZS1jb3ZpZCB2cyBjb3ZpZCkNCg0KIyMgUGVyY2VudGFnZSBvZiB3YWl0IHRpbWVzIHdpdGhpbiB0YXJnZXQgKDw0aHJzKSANCg0KYGBge3J9DQoNCiMgcHJlLWNvdmlkIDw9IDIwMTksIGNvdmlkID0+IDIwMjANCg0KYXZnX3d0X3RhcmdldF9wcmVfY292aWQgPC0gd2FpdGluZ190aW1lcyAlPiUgDQogIGZpbHRlcih5ZWFyIDw9IDIwMTkpICU+JSANCiAgZ3JvdXBfYnkobW9udGgpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICB0b3RhbF93YWl0X2x0XzRocnMgPSBzdW0od2FpdF9sdF80aHJzKSwNCiAgICAgICAgICAgIHRhcmdldF93YWl0X3Byb3AgPSB0b3RhbF93YWl0X2x0XzRocnMgLyB0b3RhbF9hdHRlbmRhbmNlKQ0KDQphdmdfd3RfdGFyZ2V0X3ByZV9jb3ZpZCAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGdlb21fc21vb3RoKHNlID0gMCkNCg0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGZpbHRlcih5ZWFyID49IDIwMjApICU+JQ0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHRvdGFsX3dhaXRfbHRfNGhycyA9IHN1bSh3YWl0X2x0XzRocnMpLA0KICAgICAgICAgICAgdGFyZ2V0X3dhaXRfcHJvcCA9IHRvdGFsX3dhaXRfbHRfNGhycyAvIHRvdGFsX2F0dGVuZGFuY2UpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB0YXJnZXRfd2FpdF9wcm9wLA0KICAgICAgICAgICAgICAgIGdyb3VwID0gZmFjdG9yKHllYXIpLCBjb2wgPSBmYWN0b3IoeWVhcikpKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBhdmdfd3RfdGFyZ2V0X3ByZV9jb3ZpZCwgYWVzKHggPSBtb250aCwgeSA9IHRhcmdldF93YWl0X3Byb3AsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IDEsIGNvbG91ciA9ICJCYXNlbGluZSIpLA0KICAgICAgICAgICAgICBzaXplID0gMSkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBhdmdfd3RfdGFyZ2V0X3ByZV9jb3ZpZCwgYWVzKHggPSBtb250aCwgeSA9IHRhcmdldF93YWl0X3Byb3AsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IDEsIGNvbG91ciA9ICJCYXNlbGluZSIpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbChuYW1lID0gIlllYXIiLCB2YWx1ZXMgPSBjKCJCYXNlbGluZSIgPSAiZGFya2JsdWUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjAyMCIgPSAicmVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMjEiID0gImdyZWVuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMjIiID0gIm9yYW5nZSIpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgbGFicyh5ID0gIlBlcmNlbnRhZ2Ugb2YgYWRtaXNzaW9ucyAoJSkiLA0KICAgICAgIHRpdGxlID0gIlByb3BvcnRpb24gb2Ygd2FpdGluZyB0aW1lcyBncmVhdGVyIHRoYW4gMTIgaG91cnMiLA0KICAgICAgIHN1YnRpdGxlID0gIlByZS1jb3ZpZCAoMjAwNy0yMDE5KSB2cyBjb3ZpZCAoMjAyMCspIiwNCiAgICAgICBjb2wgPSAiWWVhciIpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQoNCmBgYA0KDQojIyBQZXJjZW50YWdlIG9mIHdhaXQgdGltZXMgPjhocnMgDQoNCmBgYHtyfQ0KDQphdmdfd3RfZ3RfOGhyc19wcmVfY292aWQgPC0gd2FpdGluZ190aW1lcyAlPiUgDQogIGZpbHRlcih5ZWFyIDw9IDIwMTkpICU+JSANCiAgZ3JvdXBfYnkobW9udGgpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICB0b3RhbF93YWl0X2d0XzhocnMgPSBzdW0od2FpdF9ndF84aHJzKSwNCiAgICAgICAgICAgIHRhcmdldF93YWl0X3Byb3AgPSB0b3RhbF93YWl0X2d0XzhocnMgLyB0b3RhbF9hdHRlbmRhbmNlKQ0KDQphdmdfd3RfZ3RfOGhyc19wcmVfY292aWQgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtb250aCwgeSA9IHRhcmdldF93YWl0X3Byb3AsIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBnZW9tX3Ntb290aChzZSA9IDApDQoNCndhaXRpbmdfdGltZXMgJT4lIA0KICBmaWx0ZXIoeWVhciA+PSAyMDIwKSAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgbW9udGgpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksDQogICAgICAgICAgICB0b3RhbF93YWl0X2d0XzhocnMgPSBzdW0od2FpdF9ndF84aHJzKSwNCiAgICAgICAgICAgIHRhcmdldF93YWl0X3Byb3AgPSB0b3RhbF93YWl0X2d0XzhocnMgLyB0b3RhbF9hdHRlbmRhbmNlKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwNCiAgICAgICAgICAgICAgICBncm91cCA9IGZhY3Rvcih5ZWFyKSwgY29sID0gZmFjdG9yKHllYXIpKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fbGluZShkYXRhID0gYXZnX3d0X2d0XzhocnNfcHJlX2NvdmlkLCBhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gMSwgY29sb3VyID0gIkJhc2VsaW5lIiksDQogICAgICAgICAgICAgIHNpemUgPSAxKSArDQogICAgZ2VvbV9wb2ludChkYXRhID0gYXZnX3d0X2d0XzhocnNfcHJlX2NvdmlkLCBhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gMSwgY29sb3VyID0gIkJhc2VsaW5lIikpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiWWVhciIsIHZhbHVlcyA9IGMoIkJhc2VsaW5lIiA9ICJkYXJrYmx1ZSIsICIyMDIwIiA9ICJyZWQiLCAiMjAyMSIgPSAiZ3JlZW4iLCAiMjAyMiIgPSAib3JhbmdlIikpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKw0KICBsYWJzKHkgPSAiUGVyY2VudGFnZSBvZiBhZG1pc3Npb25zICglKSIsDQogICAgICAgdGl0bGUgPSAiUHJvcG9ydGlvbiBvZiB3YWl0aW5nIHRpbWVzIGdyZWF0ZXIgdGhhbiA4IGhvdXJzIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJQcmUtY292aWQgKDIwMDctMjAxOSkgdnMgY292aWQgKDIwMjArKSIsDQogICAgICAgY29sID0gIlllYXIiKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQoNCiMjIFBlcmNlbnRhZ2Ugb2Ygd2FpdCB0aW1lcyA+MTJocnMgDQoNCmBgYHtyfQ0KDQphdmdfd3RfZ3RfMTJocnNfcHJlX2NvdmlkIDwtIHdhaXRpbmdfdGltZXMgJT4lIA0KICBmaWx0ZXIoeWVhciA8PSAyMDE5KSAlPiUgDQogIGdyb3VwX2J5KG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLA0KICAgICAgICAgICAgdG90YWxfd2FpdF9ndF8xMmhycyA9IHN1bSh3YWl0X2d0XzEyaHJzKSwNCiAgICAgICAgICAgIHRhcmdldF93YWl0X3Byb3AgPSB0b3RhbF93YWl0X2d0XzEyaHJzIC8gdG90YWxfYXR0ZW5kYW5jZSkNCg0KYXZnX3d0X2d0XzEyaHJzX3ByZV9jb3ZpZCAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGdlb21fc21vb3RoKHNlID0gMCkNCg0Kd2FpdGluZ190aW1lcyAlPiUgDQogIGZpbHRlcih5ZWFyID49IDIwMjApICU+JQ0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXR0ZW5kYW5jZSA9IHN1bSh0b3RhbF9hdHRlbmRhbmNlKSwNCiAgICAgICAgICAgIHRvdGFsX3dhaXRfZ3RfMTJocnMgPSBzdW0od2FpdF9ndF8xMmhycyksDQogICAgICAgICAgICB0YXJnZXRfd2FpdF9wcm9wID0gdG90YWxfd2FpdF9ndF8xMmhycyAvIHRvdGFsX2F0dGVuZGFuY2UpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbW9udGgsIHkgPSB0YXJnZXRfd2FpdF9wcm9wLA0KICAgICAgICAgICAgICAgIGdyb3VwID0gZmFjdG9yKHllYXIpLCBjb2wgPSBmYWN0b3IoeWVhcikpKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBhdmdfd3RfZ3RfMTJocnNfcHJlX2NvdmlkLCBhZXMoeCA9IG1vbnRoLCB5ID0gdGFyZ2V0X3dhaXRfcHJvcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gMSwgY29sb3VyID0gIkJhc2VsaW5lIiksDQogICAgICAgICAgICAgIHNpemUgPSAxKSArDQogICAgZ2VvbV9wb2ludChkYXRhID0gYXZnX3d0X2d0XzEyaHJzX3ByZV9jb3ZpZCwgYWVzKHggPSBtb250aCwgeSA9IHRhcmdldF93YWl0X3Byb3AsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IDEsIGNvbG91ciA9ICJCYXNlbGluZSIpKSArDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbChuYW1lID0gIlllYXIiLCB2YWx1ZXMgPSBjKCJCYXNlbGluZSIgPSAiZGFya2JsdWUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjAyMCIgPSAicmVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMjEiID0gImdyZWVuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIwMjIiID0gIm9yYW5nZSIpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgbGFicyh5ID0gIlBlcmNlbnRhZ2Ugb2YgYWRtaXNzaW9ucyAoJSkiLA0KICAgICAgIHRpdGxlID0gIlByb3BvcnRpb24gb2Ygd2FpdGluZyB0aW1lcyBncmVhdGVyIHRoYW4gMTIgaG91cnMiLA0KICAgICAgIHN1YnRpdGxlID0gIlByZS1jb3ZpZCAoMjAwNy0yMDE5KSB2cyBjb3ZpZCAoMjAyMCspIiwNCiAgICAgICBjb2wgPSAiWWVhciIpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQpgYGANCg0KDQojIEphY2sncyBxdWVzdGlvbjoNCg0KYGBge3J9DQoNCmJlZHNfdHJlYXRtZW50X3NwZWNpYWx0eSA8LSBiZWRzDQoNCg0KZGYxIDwtIGJlZHNfdHJlYXRtZW50X3NwZWNpYWx0eSAlPiUgI3ByZSBjb3ZpZCBkYXRlcywgYWxsIGhlYWx0aCBiYW9yZHMNCiAgbXV0YXRlKGRhdGUgPSB5cShxdWFydGVyKSwgbW9udGggPSBtb250aChkYXRlLCBsYWJlbCA9IFRSVUUsIGFiYnIgPSBUUlVFKSwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGUpKSAlPiUgDQogIGZpbHRlcih5ZWFyIDw9IDIwMTksIGhiID09ICJTMDgwMDAwMTUiKSAlPiUgIyBoYiBzZWxlY3RlZCBieSB1c2VyIGlucHV0DQogIGdyb3VwX2J5KG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfb2NjdXBhbmN5ID0gbWVhbihwZXJjZW50YWdlX29jY3VwYW5jeSwgbmEucm0gPSBUUlVFKSkNCg0KDQpkZjIgPC0gYmVkc190cmVhdG1lbnRfc3BlY2lhbHR5ICU+JSANCiAgbXV0YXRlKGRhdGUgPSB5cShxdWFydGVyKSwgbW9udGggPSBtb250aChkYXRlLCBsYWJlbCA9IFRSVUUsIGFiYnIgPSBUUlVFKSwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGUpKSAlPiUgDQogIGZpbHRlcih5ZWFyID4gMjAxOSwgaGIgPT0gIlMwODAwMDAxNSIpICU+JSAjcG9zdCBjb3ZpZCwgZmlsdGVyIGJhc2VkIG9uIG1hcCBpbnB1dA0KICBncm91cF9ieSh5ZWFyLCBtb250aCkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX29jY3VwYW5jeSA9IG1lYW4ocGVyY2VudGFnZV9vY2N1cGFuY3ksIG5hLnJtID0gVFJVRSkpDQoNCiMjIG5vIGxvbmdlciByZXF1aXJlZA0KIyBkZjMgPC0gZGYxICU+JSANCiMgICBtdXRhdGUoVHlwZSA9ICJiYXNlbGluZSIpICU+JSANCiMgICBiaW5kX3Jvd3MoZGYyICU+JSANCiMgICAgICAgICAgICAgICBtdXRhdGUoVHlwZSA9ICJwb3N0LWNvdmlkIikpDQoNCmRmMiAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gYXZnX29jY3VwYW5jeSwgY29sb3VyID0gZmFjdG9yKHllYXIpLCBncm91cCA9IHllYXIpKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBkZjEsIGFlcyh4ID0gbW9udGgsIHkgPSBhdmdfb2NjdXBhbmN5LCBncm91cCA9IDEsIGNvbCA9ICJCYXNlbGluZSIpKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IGRmMSwgYWVzKHggPSBtb250aCwgeSA9IGF2Z19vY2N1cGFuY3ksIGdyb3VwID0gMSwgY29sID0gIkJhc2VsaW5lIikpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiWWVhciIsIHZhbHVlcyA9IGMoIkJhc2VsaW5lIiA9ICJkYXJrYmx1ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyMDIwIiA9ICJyZWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjAyMSIgPSAiZ3JlZW4iKSkgKw0KICBsYWJzKHRpdGxlID0gIkF2ZyBPY2N1cGFuY3kgYnkgSGVhbHRoIEJvYXJkIHZzIEJhc2VsaW5lIiwgIyBuZWVkIHRvIHVwZGF0ZSB0aGVzZQ0KICAgICAgIHggPSAiTW9udGgiLA0KICAgICAgIHkgPSAiQXZnIE9jY3VwYW5jeSBSYXRlIikNCg0KDQpkZjJfd2lkZSA8LSBkZjIgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0geWVhciwgdmFsdWVzX2Zyb20gPSBhdmdfb2NjdXBhbmN5KQ0KDQpkZjEyIDwtIGRmMSAlPiUgDQogIHJlbmFtZShiYXNlbGluZSA9IGF2Z19vY2N1cGFuY3kpICU+JSANCiAgbGVmdF9qb2luKGRmMl93aWRlLCAibW9udGgiKQ0KDQpkZjEyDQpgYGANCg0KYGBge3J9DQoNCmRmMyA8LSBiZWRzX3RyZWF0bWVudF9zcGVjaWFsdHkgJT4lICNwcmUgY292aWQgZGF0ZXMsIGFsbCBoZWFsdGggYmFvcmRzDQogIG11dGF0ZShkYXRlID0geXEocXVhcnRlciksIG1vbnRoID0gbW9udGgoZGF0ZSwgbGFiZWwgPSBUUlVFLCBhYmJyID0gVFJVRSksDQogICAgICAgICB5ZWFyID0geWVhcihkYXRlKSkgJT4lIA0KICBmaWx0ZXIoeWVhciA8PSAyMDE5LCBoYiA9PSAiUzA4MDAwMDE1IikgJT4lICMgaGIgc2VsZWN0ZWQgYnkgdXNlciBpbnB1dA0KICBncm91cF9ieShtb250aCkgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfYXZhaWxhYmxlID0gc3VtKGFsbF9zdGFmZmVkX2JlZGRheXMpLCANCiAgICAgICAgICAgIHRvdGFsX29jY3VwaWVkID0gc3VtKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpLA0KICAgICAgICAgICAgYXZnX29jY3VwYW5jeSA9IHRvdGFsX29jY3VwaWVkIC8gdG90YWxfYXZhaWxhYmxlKQ0KDQoNCmRmNCA8LSBiZWRzX3RyZWF0bWVudF9zcGVjaWFsdHkgJT4lIA0KICBtdXRhdGUoZGF0ZSA9IHlxKHF1YXJ0ZXIpLCBtb250aCA9IG1vbnRoKGRhdGUsIGxhYmVsID0gVFJVRSwgYWJiciA9IFRSVUUpLA0KICAgICAgICAgeWVhciA9IHllYXIoZGF0ZSkpICU+JSANCiAgZmlsdGVyKHllYXIgPiAyMDE5LCBoYiA9PSAiUzA4MDAwMDE1IikgJT4lICNwb3N0IGNvdmlkLCBmaWx0ZXIgYmFzZWQgb24gbWFwIGlucHV0DQogIGdyb3VwX2J5KHllYXIsIG1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbF9hdmFpbGFibGUgPSBzdW0oYWxsX3N0YWZmZWRfYmVkZGF5cyksIA0KICAgICAgICAgICAgdG90YWxfb2NjdXBpZWQgPSBzdW0odG90YWxfb2NjdXBpZWRfYmVkZGF5cyksDQogICAgICAgICAgICBhdmdfb2NjdXBhbmN5ID0gdG90YWxfb2NjdXBpZWQgLyB0b3RhbF9hdmFpbGFibGUpDQoNCmRmNCAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gYXZnX29jY3VwYW5jeSwgY29sb3VyID0gZmFjdG9yKHllYXIpLCBncm91cCA9IHllYXIpKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBkZjMsIGFlcyh4ID0gbW9udGgsIHkgPSBhdmdfb2NjdXBhbmN5LCBncm91cCA9IDEsIGNvbCA9ICJCYXNlbGluZSIpKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IGRmMywgYWVzKHggPSBtb250aCwgeSA9IGF2Z19vY2N1cGFuY3ksIGdyb3VwID0gMSwgY29sID0gIkJhc2VsaW5lIikpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiWWVhciIsIHZhbHVlcyA9IGMoIkJhc2VsaW5lIiA9ICJkYXJrYmx1ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyMDIwIiA9ICJyZWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjAyMSIgPSAiZ3JlZW4iKSkgKw0KICBsYWJzKHRpdGxlID0gIkF2ZyBPY2N1cGFuY3kgYnkgSGVhbHRoIEJvYXJkIHZzIEJhc2VsaW5lIiwgIyBuZWVkIHRvIHVwZGF0ZSB0aGVzZQ0KICAgICAgIHggPSAiTW9udGgiLA0KICAgICAgIHkgPSAiQXZnIE9jY3VwYW5jeSBSYXRlIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KQ0KDQoNCmRmNF93aWRlIDwtIGRmMiAlPiUgDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSB5ZWFyLCB2YWx1ZXNfZnJvbSA9IGF2Z19vY2N1cGFuY3kpDQoNCmRmMzQgPC0gZGYzICU+JSANCiAgcmVuYW1lKGJhc2VsaW5lID0gYXZnX29jY3VwYW5jeSkgJT4lIA0KICBsZWZ0X2pvaW4oZGYyX3dpZGUsICJtb250aCIpICU+JSANCiAgc2VsZWN0KC10b3RhbF9hdmFpbGFibGUsIC0gdG90YWxfb2NjdXBpZWQpICU+JSANCiAgbXV0YXRlKGJhc2VsaW5lID0gYmFzZWxpbmUgKiAxMDApDQoNCmBgYA0KDQpgYGB7cn0NCiMgd2VpZ2h0ZWQgYXZlcmFnZSBvY2N1cGFuY3kgcmF0ZQ0KZGYzNA0KDQpgYGANCg0KYGBge3J9DQojIGF2ZXJhZ2Ugb2Ygb2NjdXBhbmN5IHBlcmNlbnRhZ2VzDQpkZjEyDQoNCmBgYA0KIyBob3cgZG9lcyBiZWQgdXNhZ2UgY2hhbmdlIG92ZXIgdGltZQ0KYGBge3J9DQoNCmJlZHMgJT4lDQogIGdyb3VwX2J5KHF1YXJ0ZXIpICU+JQ0KICBzdW1tYXJpc2UoYmVkc19hdmFpbGFibGUgPSBzdW0oYWxsX3N0YWZmZWRfYmVkZGF5cyksDQogICAgICAgICAgICBiZWRzX29jY3VwaWVkID0gc3VtKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGJlZHNfYXZhaWxhYmxlOmJlZHNfb2NjdXBpZWQsIG5hbWVzX3RvID0gImJlZF90eXBlIiwNCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJudW1fYmVkcyIpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IG51bV9iZWRzLCBjb2xvdXIgPSBiZWRfdHlwZSwgZ3JvdXAgPSBiZWRfdHlwZSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpjb21tYSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIGxhYnMoeSA9ICJOdW1iZXIgb2YgYmVkIGRheXMiLA0KICAgICAgIHRpdGxlID0gIk51bWJlciBvZiBiZWRzIGF2YWlsYWJsZS9vY2N1cGllZCBvdmVyIHRpbWUiLA0KICAgICAgIGNvbCA9ICJCZWQgVHlwZSIpDQoNCmBgYA0KIyBiZWQgdXNlIGJ5IHNwZWNpYWx0eQ0KYGBge3J9DQoNCmJlZHMgJT4lDQogIGdyb3VwX2J5KHF1YXJ0ZXIsIHNwZWNpYWx0eV9uYW1lKSAlPiUNCiAgIyBmaWx0ZXIoc3BlY2lhbHR5X25hbWUgJWluJSBjKCJDbGluaWNhbCBSYWRpb2xvZ3kiLCAiSW50ZW5zaXZlIENhcmUgTWVkaWNpbmUiKSkgJT4lIA0KICBzdW1tYXJpc2UoYmVkc19hdmFpbGFibGUgPSBzdW0oYWxsX3N0YWZmZWRfYmVkZGF5cyksDQogICAgICAgICAgICBiZWRzX29jY3VwaWVkID0gc3VtKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGJlZHNfYXZhaWxhYmxlOmJlZHNfb2NjdXBpZWQsIG5hbWVzX3RvID0gImJlZF90eXBlIiwNCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJudW1fYmVkcyIpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcXVhcnRlciwgeSA9IG51bV9iZWRzLCBjb2xvdXIgPSBzcGVjaWFsdHlfbmFtZSwgZ3JvdXAgPSBzcGVjaWFsdHlfbmFtZSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBmYWNldF93cmFwKH5iZWRfdHlwZSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpjb21tYSkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIGxhYnMoeSA9ICJOdW1iZXIgb2YgYmVkIGRheXMiLA0KICAgICAgIHRpdGxlID0gIk51bWJlciBvZiBiZWRzIGF2YWlsYWJsZS9vY2N1cGllZCBvdmVyIHRpbWUiLA0KICAgICAgIGNvbCA9ICJCZWQgVHlwZSIpDQoNCmBgYA0KDQpgYGB7cn0NCg0KYmVkcyAlPiUgDQogIG11dGF0ZSh5ZWFyID0gYXMubnVtZXJpYyhzdHJfZXh0cmFjdChxdWFydGVyLCAiWzAtOV17NH0iKSksDQogICAgaXNfY292aWRfeWVhciA9IGNhc2Vfd2hlbigNCiAgICB5ZWFyIDw9IDIwMTkgfiBGQUxTRSwNCiAgICB5ZWFyID49IDIwMjAgfiBUUlVFDQogICAgKSkgJT4lIA0KICBncm91cF9ieShzcGVjaWFsdHlfbmFtZSwgaXNfY292aWRfeWVhcikgJT4lIA0KICBzdW1tYXJpc2UoYmVkc19hdmFpbGFibGUgPSBzdW0oYWxsX3N0YWZmZWRfYmVkZGF5cyksDQogICAgICAgICAgICBiZWRzX29jY3VwaWVkID0gc3VtKHRvdGFsX29jY3VwaWVkX2JlZGRheXMpKSAlPiUgDQogIHNlbGVjdChzcGVjaWFsdHlfbmFtZSwgaXNfY292aWRfeWVhciwgYmVkc19vY2N1cGllZCkgJT4lICANCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGlzX2NvdmlkX3llYXIsIHZhbHVlc19mcm9tID0gYmVkc19vY2N1cGllZCkgJT4lIA0KICByZW5hbWUoInByZV9jb3ZpZCIgPSAiRkFMU0UiLCAiY292aWQiID0gIlRSVUUiKSAlPiUgDQogIGRyb3BfbmEoKSAlPiUgDQogIG11dGF0ZShkaWZmX29jY3VwaWVkID0gY292aWQgLSBwcmVfY292aWQsDQogICAgICAgICBkaWZmX29jY3VwaWVkX3BjID0gKChjb3ZpZCAvIHByZV9jb3ZpZCkgLSAxKSAqIDEwMCkgJT4lIA0KICBmaWx0ZXIoZGlmZl9vY2N1cGllZF9wYyA+IDApICU+JSANCiAgYXJyYW5nZShkZXNjKGRpZmZfb2NjdXBpZWRfcGMpKQ0KICANCg0KYGBgDQojIHdhaXRpbmcgdGltZXMNCiMjIGNsZWFuaW5nDQpgYGB7cn0NCg0KaGIgPC0gcmVhZF9jc3YoaGVyZSgiY2xlYW5fZGF0YS9oYl9saXN0X3NpbXBsZS5jc3YiKSkNCg0Kd2FpdGluZ190aW1lcyA8LSB3YWl0aW5nX3RpbWVzX3JhdyAlPiUgDQogIG11dGF0ZShkYXRlX3ltID0geW0obW9udGgpLCAuYmVmb3JlID0gbW9udGgsDQogICAgICAgICBtb250aCA9IG1vbnRoKGRhdGVfeW0sIGxhYmVsID0gVFJVRSwgYWJiciA9IEZBTFNFKSwNCiAgICAgICAgIHllYXIgPSB5ZWFyKGRhdGVfeW0pKSAlPiUgDQogIGxlZnRfam9pbihoYiwgYygiaGJ0IiA9ICJoYiIpKSAlPiUgDQogIGxlZnRfam9pbihob3NwaXRhbHMsIGMoInRyZWF0bWVudF9sb2NhdGlvbiIgPSAibG9jYXRpb24iKSkgJT4lIA0KICByZW5hbWUodG90YWxfYXR0ZW5kYW5jZSA9IG51bWJlcl9vZl9hdHRlbmRhbmNlc19hZ2dyZWdhdGUsDQogICAgICAgICB3YWl0X2x0XzRocnMgPSBudW1iZXJfbWVldGluZ190YXJnZXRfYWdncmVnYXRlLA0KICAgICAgICAgd2FpdF9ndF84aHJzID0gYXR0ZW5kYW5jZV9ncmVhdGVyOGhycywNCiAgICAgICAgIHdhaXRfZ3RfMTJocnMgPSBhdHRlbmRhbmNlX2dyZWF0ZXIxMmhycywNCiAgICAgICAgIGhvc3BpdGFsX2lkID0gdHJlYXRtZW50X2xvY2F0aW9uLCANCiAgICAgICAgIGhvc3BpdGFsX25hbWUgPSBsb2NhdGlvbl9uYW1lKSAlPiUgDQogIHNlbGVjdChkYXRlX3ltLCB5ZWFyLCBtb250aCwgaGJfbmFtZSwgaG9zcGl0YWxfaWQsIGhvc3BpdGFsX25hbWUsIGRlcGFydG1lbnRfdHlwZSwNCiAgICAgICAgIHRvdGFsX2F0dGVuZGFuY2UsIHdhaXRfbHRfNGhycywgd2FpdF9ndF84aHJzLCB3YWl0X2d0XzEyaHJzKSAlPiUgDQogIG11dGF0ZSh3YWl0X2d0XzRocnMgPSB0b3RhbF9hdHRlbmRhbmNlIC0gd2FpdF9sdF80aHJzLCAuYWZ0ZXIgPSB3YWl0X2x0XzRocnMpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHRvdGFsX2F0dGVuZGFuY2U6d2FpdF9ndF8xMmhycywgLmZucyA9IH5jb2FsZXNjZSguLCAwKSkpDQoNCmBgYA0KDQojIyBhbmFseXNpcw0KYGBge3J9DQoNCndhaXRpbmdfdGltZXMgJT4lIA0KICBtdXRhdGUoaXNfY292aWRfeWVhciA9IGNhc2Vfd2hlbigNCiAgICB5ZWFyIDw9IDIwMTkgfiBGQUxTRSwNCiAgICB5ZWFyID49IDIwMjAgfiBUUlVFDQogICkpICU+JSANCiAgZ3JvdXBfYnkoaXNfY292aWRfeWVhcikgJT4lIA0KICBzdW1tYXJpc2Uoc3VtX2F0dGVuZGFuY2UgPSBzdW0odG90YWxfYXR0ZW5kYW5jZSksIA0KICAgICAgICAgICAgd2FpdF90YXJnZXQgPSBzdW0od2FpdF9sdF80aHJzKSkgJT4lIA0KICBwaXZvdF9sb25nZXIod2FpdF90YXJnZXQsIG5hbWVzX3RvID0gIndhaXRfdGltZSIsIHZhbHVlc190byA9ICJ2YWx1ZSIpICU+JSANCiAgbXV0YXRlKHByb3BvcnRpb24gPSB2YWx1ZSAvIHN1bV9hdHRlbmRhbmNlKSAlPiUgDQogIGdncGxvdChhZXMoeW1heCA9IHByb3BvcnRpb24sIHltaW4gPSAwLCB4bWF4ID0gMiwgeG1pbiA9IDEsIGZpbGwgPSBwcm9wb3J0aW9uKSkgKw0KICBnZW9tX3JlY3QoYWVzKHltYXggPSAxLCB5bWluID0gMCwgeG1heCA9IDIsIHhtaW4gPSAxKSwgZmlsbCA9ICJncmV5ODAiKSArDQogIGdlb21fcmVjdCgpICsgDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gInkiLHN0YXJ0PS1waS8yKSArIHhsaW0oYygwLCAyKSkgKyB5bGltKGMoMCwyKSkgKw0KICBnZW9tX3RleHQoYWVzKHggPSAwLCB5ID0gMCwgbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQocHJvcG9ydGlvbiwgYWNjdXJhY3kgPSAwLjEpKSwgc2l6ZSA9IDYuNSkgKw0KICBnZW9tX3RleHQoYWVzKHggPSAwLjUsIHkgPSAxLjUpLCBsYWJlbCA9IGMoIlByZS1Db3ZpZCIsICJEdXJpbmcgQ292aWQiKSwgZmFtaWx5PSJQb3BwaW5zIExpZ2h0Iiwgc2l6ZT00LjIpICsgDQogIGZhY2V0X3dyYXAofmlzX2NvdmlkX3llYXIsIG5yb3cgPSAxKSArDQogIHRoZW1lX3ZvaWQoKSArDQogICMgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygicmVkIj0iI0M5MTQ2QyIsICJvcmFuZ2UiPSIjREE5MTEyIiwgImdyZWVuIj0iIzEyOTE4OCIpKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygicmVkIj0iI0M5MTQ2QyIsICJvcmFuZ2UiPSIjREE5MTEyIiwgImdyZWVuIj0iIzEyOTE4OCIpKSArDQogIHRoZW1lKHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQojICwNCiMgICAgICAgICAgKw0KICBsYWJzKHRpdGxlID0gIiAgIFBlcmNlbnRhZ2Ugb2YgYWRtaXNzaW9ucyBhY2hpZXZpbmcgdGFyZ2V0IHdhaXQgdGltZXMgKDw0aHJzKSIpDQoNCg0KYGBgDQoNCg0KYGBge3J9DQoNCmxpYnJhcnkoZ2dmb3JjZSkNCmxpYnJhcnkoc2NhbGVzKQ0KDQp3YWl0aW5nX3RpbWVzICU+JSANCiAgbXV0YXRlKGlzX2NvdmlkX3llYXIgPSBjYXNlX3doZW4oDQogICAgeWVhciA8PSAyMDE5IH4gRkFMU0UsDQogICAgeWVhciA+PSAyMDIwIH4gVFJVRQ0KICApKSAlPiUgDQogIGdyb3VwX2J5KGlzX2NvdmlkX3llYXIpICU+JSANCiAgc3VtbWFyaXNlKHN1bV9hdHRlbmRhbmNlID0gc3VtKHRvdGFsX2F0dGVuZGFuY2UpLCANCiAgICAgICAgICAgIHdhaXRfdGFyZ2V0ID0gc3VtKHdhaXRfbHRfNGhycykpICU+JSANCiAgcGl2b3RfbG9uZ2VyKHdhaXRfdGFyZ2V0LCBuYW1lc190byA9ICJ3YWl0X3RpbWUiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKSAlPiUgDQogIG11dGF0ZShwcm9wb3J0aW9uID0gdmFsdWUgLyBzdW1fYXR0ZW5kYW5jZSkgJT4lDQogIG11dGF0ZSh5bWluID0gcmVzY2FsZSgwLCB0byA9IHBpKmMoLS41LC41KSwgZnJvbSA9IDA6MSksIA0KICAgICAgICAgeW1heCA9IHJlc2NhbGUocHJvcG9ydGlvbiwgdG8gPSBwaSpjKC0uNSwuNSksIGZyb20gPSAwOjEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4MCA9IDAsIHkwID0gMCwgcjAgPSAuNSwgciA9IDEpKSArIA0KICBnZW9tX2FyY19iYXIoYWVzKHN0YXJ0ID0gLSBwaSAvIDIsIGVuZCA9IHBpIC8gMiksIGZpbGwgPSAiZ3JleTgwIikgKw0KICBnZW9tX2FyY19iYXIoYWVzKHgwID0gMCwgeTAgPSAwLCByMCA9IC41LCByID0gMSwgc3RhcnQgPSB5bWluLCBlbmQgPSB5bWF4LCBmaWxsID0gcHJvcG9ydGlvbikpICsNCiAgY29vcmRfZml4ZWQoKSArDQogIGZhY2V0X3dyYXAofiBpc19jb3ZpZF95ZWFyKSArDQogIHlsaW0oLTAuMywgMSkgKw0KICBnZW9tX3RleHQoYWVzKHggPSAwLCB5ID0gMC4wMSwgbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQocHJvcG9ydGlvbiwgYWNjdXJhY3kgPSAwLjEpKSwgc2l6ZSA9IDYuNSkgKw0KICBnZW9tX3RleHQoYWVzKHggPSAwLCB5ID0gLTAuMjUpLCBsYWJlbCA9IGMoIlByZS1Db3ZpZCIsICJEdXJpbmcgQ292aWQiKSwgZmFtaWx5PSAiUG9wcGlucyBMaWdodCIsIHNpemU9NC4yKSArDQogIHRoZW1lX3ZvaWQoKSArDQogICAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMSksDQogICAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMCwgMCwgMCwgMCksICJjbSIpKSArDQogIGxhYnModGl0bGUgPSAiICAgUGVyY2VudGFnZSBvZiBhZG1pc3Npb25zIGFjaGlldmluZyB0YXJnZXQgd2FpdCB0aW1lcyAoPDRocnMpXG4iKQ0KDQogIA0KDQpgYGANCg0KIyBDb2xvdXIgcGFsZXR0ZQ0KDQpgYGB7cn0NCg0KcGFsIDwtIGMocmdiKDE5OSwgMTc1LCAxMTcsIG1heENvbG9yVmFsdWUgPSAyNTUpLA0KICAgICAgICAgcmdiKDEyNCwgMzYsIDI0LCBtYXhDb2xvclZhbHVlID0gMjU1KSwgDQogICAgICAgICByZ2IoMjEwLCAyMjEsIDIxMywgbWF4Q29sb3JWYWx1ZSA9IDI1NSksIA0KICAgICAgICAgcmdiKDE2OCwgMTA2LCA1NywgbWF4Q29sb3JWYWx1ZSA9IDI1NSksIA0KICAgICAgICAgcmdiKDIyMiwgMjI0LCAyMjcsIG1heENvbG9yVmFsdWUgPSAyNTUpLA0KICAgICAgICAgcmdiKDE4NiwgMTU4LCA1MywgbWF4Q29sb3JWYWx1ZSA9IDI1NSksIA0KICAgICAgICAgcmdiKDYsIDU3LCA4MywgbWF4Q29sb3JWYWx1ZSA9IDI1NSksIA0KICAgICAgICAgcmdiKDEwOSwgNjcsIDg1LCBtYXhDb2xvclZhbHVlID0gMjU1KQ0KKQ0KDQpzaG93X2NvbChwYWwpDQoNCg0KDQpgYGANCg0KIyBSb2IncyBwcm9ibGVtIA0KDQpgYGB7cn0NCg0KDQoNCiBpbnBhdGllbnRfYW5kX2RheWNhc2VfYnlfbmhzX2JvYXJkX29mX3RyZWF0bWVudF9hbmRfc2ltZF9ub25fY292aWRfY2xlYW5lZCAlPiUNCiAgc2VsZWN0KHF1YXJ0ZXJfeWVhciwgeWVhciwgaGJfbmFtZSwgc2ltZCwgYWRtaXNzaW9uX3R5cGUsIHN0YXlzLCBpc19jb3ZpZF95ZWFyKSAlPiUNCiAgZmlsdGVyKHN0YXlzID4wKSAlPiUNCiAgZmlsdGVyKGhiX25hbWUgIT0gIiIpICU+JQ0KICBmaWx0ZXIoIWlzLm5hKHNpbWQpKSAlPiUNCiAgZ3JvdXBfYnkoaXNfY292aWRfeWVhciwgc3RheXMsIHF1YXJ0ZXJfeWVhciwgc2ltZCkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9zdGF5cyA9IHN1bShzdGF5cykpICU+JQ0KICBkaXN0aW5jdCgpICU+JQ0KICBnZ3Bsb3QoKSsNCiAgYWVzKHggPSBxdWFydGVyX3llYXIsIHkgPSB0b3RhbF9zdGF5cywgZmlsbCA9IHNpbWQpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikNCg0KYGBgDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KZGYgPC0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9wbG90bHkvZGF0YXNldHMvbWFzdGVyLzIwMTFfdXNfYWdfZXhwb3J0cy5jc3YiKQ0KZGYkaG92ZXIgPC0gd2l0aChkZiwgcGFzdGUoc3RhdGUsICc8YnI+JywgIkJlZWYiLCBiZWVmLCAiRGFpcnkiLCBkYWlyeSwgIjxicj4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZydWl0cyIsIHRvdGFsLmZydWl0cywgIlZlZ2dpZXMiLCB0b3RhbC52ZWdnaWVzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj4iLCAiV2hlYXQiLCB3aGVhdCwgIkNvcm4iLCBjb3JuKSkNCg0KZmlnIDwtIHBsb3RfZ2VvKGRmLCBsb2NhdGlvbm1vZGUgPSAnVVNBLXN0YXRlcycpDQpmaWcgPC0gZmlnICU+JSBhZGRfdHJhY2UoDQogICAgeiA9IH50b3RhbC5leHBvcnRzLCB0ZXh0ID0gfmhvdmVyLCBsb2NhdGlvbnMgPSB+Y29kZSwNCiAgICBjb2xvciA9IH50b3RhbC5leHBvcnRzLCBjb2xvcnMgPSAnUHVycGxlcycNCiAgKQ0KZmlnIDwtIGZpZyAlPiUgY29sb3JiYXIodGl0bGUgPSAiTWlsbGlvbnMgVVNEIikNCmZpZyA8LSBmaWcgJT4lIGxheW91dCgNCiAgICB0aXRsZSA9ICcyMDExIFVTIEFncmljdWx0dXJlIEV4cG9ydHMgYnkgU3RhdGU8YnI+KEhvdmVyIGZvciBicmVha2Rvd24pJw0KICApDQoNCmZpZw0KDQpgYGANCg0KYGBge3J9DQoNCmhlYWx0aF9ib2FyZF9tYXAgJT4lDQogIHBsb3RfZ2VvKGxvY2F0aW9ubW9kZSA9ICJTY290bGFuZCIpICU+JSANCiAgYWRkX3RyYWNlKHRleHQgPSB+aGJfbmFtZSkNCiAgICAgIGdncGxvdChhZXModGV4dCA9IGhiX25hbWUpKSArDQogICAgICBnZW9tX3NmKGZpbGwgPSBwYWxbNV0sIGNvbCA9ICJncmF5NDAiLCBzaXplID0gMC4xKSArDQogICAgICBnZW9tX3NmKGRhdGEgPSBoZWFsdGhfYm9hcmRfbWFwICU+JSBmaWx0ZXIoaGJfbmFtZSAlaW4lIGlucHV0JGhlYWx0aF9ib2FyZF9pbnB1dCksDQogICAgICAgICAgICAgIGZpbGwgPSBwYWxbN10sIHNpemUgPSAwLjEsIGNvbG91ciA9ICJ3aGl0ZSIpICsNCiAgICAgIHRoZW1lX3ZvaWQoKQ0KICAgIA0KICAgIGdncGxvdGx5KHAsDQogICAgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lIA0KICAgICAgY29uZmlnKHNjcm9sbFpvb20gPSBUUlVFLA0KICAgICAgICAgICAgIGRpc3BsYXlNb2RlQmFyID0gRiwNCiAgICAgICAgICAgICBzaG93QXhpc0RyYWdIYW5kbGVzID0gRikNCg0KYGBgDQoNCg==